获取对象数据的浅拷贝的最快方法是啥?

Posted

技术标签:

【中文标题】获取对象数据的浅拷贝的最快方法是啥?【英文标题】:What is the fastest way to get a shallow copy the data of an object?获取对象数据的浅拷贝的最快方法是什么? 【发布时间】:2022-01-19 06:13:38 【问题描述】:

请只使用原版 JS

也就是说,它的输出应该是一个只包含数据的对象,而忽略了原始的方法/原型。从默认Object 继承的复杂数据结构,如Array,可以以浅层方式复制,作为引用。我现在的做法是:

function shallowCopyObjectData(obj) 
  output = ;
  for (var i in item) 
    output[i] = obj[i];
  
  return output;
;

我见过的另一种方式是:

function shallowCopyObjectData(obj) 
  return JSON.parse(JSON.stringify(obj));
;

最高效的方法是什么?

我制作了一个正在运行的 jsPerf 来比较速度。如果您提出解决方案,请随时 fork 并添加:http://jsperf.com/shallow-object-data-copy

编辑 @Barmar:我知道similar question has already been posted,但它询问了克隆对象的最快方法,这意味着保留构造函数、原型等的深层副本。这个问题询问仅复制数据的最快方法顶层

【问题讨论】:

@Barmar,我认为将其标记为重复是不公平的。另一个问题询问克隆对象的最快方法,这意味着保留构造函数、原型等的深层副本。这个问题询问仅复制顶层数据的最快方法。我觉得这是两种不同的东西...... 轶事示例:我有一个 Web 应用程序可以遍历和缓存 53,000 个对象的数据。它在运行时给我的节点应用程序带来了巨大的延迟,最多需要 75829 毫秒才能完成加载所有内容。我用解析/字符串化交换它,它加速到 718 毫秒。 你真的需要对整个对象进行浅拷贝吗?或者是否有一些您可以使用的可预测的属性名称集? 我想补充一点,函数似乎没有正确地使用 parse/stringify 保存。 :| 如果您的对象已知具有相同的结构(表格数据),您可以生成克隆器。并获得巨大的性能提升,因为您的对象将共享相同的隐藏类。 jsperf.com/shallow-object-data-copy/3 【参考方案1】:

我想你问的是深度克隆(复制)。浅拷贝就像将原始对象分配给新变量一样简单。

var originalObj =  someKey: 1 ;
var copyObj = originalObj; 

【讨论】:

我认为有很大的不同。分配引用不会创建新对象,浅拷贝会。在您给出的示例中,copyObj === originalObj 将给出true,但对于浅拷贝,它应该是false 这完全是错误的。你混合了身份和价值。您可以为新标识(变量名)分配一个值,而无需复制基础值。 OP 询问浅拷贝。这只能发生在操作定义的实际值上。 Object.assign 或 JS 传播运算符又名 ...obj 是要走的路。【参考方案2】:

Object.assign() 方法用于将所有可枚举自身属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。 如果目标对象中的属性具有相同的键,它们将被源中的属性覆盖。

var obj =  a: 1, b: 2, ;
var new_obj = Object.assign(, obj);
console.log(new_obj); // a: 1, b: 2, 
console.log(new_obj == obj); //false

【讨论】:

嗨 - 您能否为您的答案添加更多上下文/解释? :) eslint 建议使用扩展运算符var new_obj = ...obj,它适用于所有现代网络浏览器:developer.mozilla.org/en-US/docs/Web/javascript/Reference/…【参考方案3】:

您可以使用Object.assign 快速克隆对象。语法为Object. assign(originObject, extendObject)。它将返回具有 originObject 和 extendObject 属性的对象。

例如我这里有代码:

var originObject = value: 1;
var extendObject = key: 2;
var shadowObject = ;

// Now I want clone originObject to shadow object
shadowObject = Object. assign(originObject, );
// shadowObject = value: 1

// If you want clone originObject and extendObject to one object
shadowObject = Object. assign(originObject, shadowObject);
// shadowObject = value: 1, key: 2

【讨论】:

以上是关于获取对象数据的浅拷贝的最快方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

js 对象的浅拷贝和深拷贝

Perl的浅拷贝和深度拷贝

Java对象的浅拷贝和深拷贝&&String类型的赋值

对象的浅拷贝与深拷贝

js中对象的浅拷贝和深拷贝的区别

python的浅拷贝和深拷贝