获取对象数据的浅拷贝的最快方法是什么

What is the fastest way to get a shallow copy the data of an object?

本文关键字:方法 是什么 浅拷贝 取对象 数据 获取      更新时间:2023-09-26

请仅使用香草 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来比较速度。 如果您想出解决方案,请随时分叉并添加:http://jsperf.com/shallow-object-data-copy

编辑@Barmar:我知道已经发布了类似的问题,但它询问了克隆对象的最快方法,这意味着保留构造函数、原型等的深层副本。 此问题询问仅复制顶层数据的最快方法

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

如今,您可以使用点差;

var o = {a:1,b:2,c:3},
    r = {...o}; // shallow clone
r.a = 11;       // r's "a" property is set to 11
console.log(r); // check
console.log(o); // r is not a reference to a

您可以使用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}

请注意,如果您事先知道属性名称,则可以通过将它们写在对象文字中来获得多个数量级的改进:

function cloneObject(obj) = {
    return {
        "property1": obj.property1,
        "property2": obj.property2,
        //Etc.
    }
}

任何涉及循环的东西都会很慢,所以如果有一个简单的方法来避免循环,那就去做吧。

以下是我最近运行的一些测试的结果(截至 4 月)2023)版浏览器:

  • structuredClone(obj) : 每毫秒 200 份
  • JSON.parse(JSON.stringify(obj)) : 每毫秒 400 份
  • 使用 Object.keys() 获取对象的属性,并使用 while 循环遍历它们,在每次迭代时从列表中删除第一个元素:每毫秒 2000 个副本。
  • 使用 Object.keys 获取对象的属性并使用 forEach() 遍历它们:每毫秒 2100 个副本。
  • 使用 Object.keys() 获取对象的属性,并使用传统的 for 循环遍历它们:每毫秒 2250 个副本。
  • 循环访问预定义的属性列表,for... of:每毫秒 2300 个副本。
  • {...obj} : 每毫秒 2500 份
  • Object.assign({}, obj) : 每毫秒 3100 份
  • 具有预定义属性的对象文本:每毫秒 100 万个副本。

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

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