按值复制数组

新手上路,请多包涵

将 JavaScript 中的数组复制到另一个数组时:

var arr1 = ['a','b','c'];
var arr2 = arr1;
arr2.push('d');  //Now, arr1 = ['a','b','c','d']

我意识到 arr2 指的是与 arr1 相同的数组,而不是一个新的独立数组。如何复制数组以获得两个独立的数组?

原文由 Dan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 874
2 个回答

用这个:

 let oldArray = [1, 2, 3, 4, 5];

 let newArray = oldArray.slice();

 console.log({newArray});

基本上, slice() 操作会克隆数组并返回对新数组的引用。

另请注意:

对于引用、字符串和数字(而不是实际对象), slice() 将对象引用复制到新数组中。 原始数组和新数组都引用同一个对象。如果引用的对象发生更改,则更改对新数组和原始数组都可见。

字符串和数字等原语是不可变的,因此不可能更改字符串或数字。

原文由 Saket 发布,翻译遵循 CC BY-SA 4.0 许可协议

在 Javascript 中,深度复制技术依赖于数组中的元素。让我们从那里开始。

三种元素

元素可以是:文字值、文字结构或原型。

 // Literal values (type1)
const booleanLiteral = true;
const numberLiteral = 1;
const stringLiteral = 'true';

// Literal structures (type2)
const arrayLiteral = [];
const objectLiteral = {};

// Prototypes (type3)
const booleanPrototype = new Bool(true);
const numberPrototype = new Number(1);
const stringPrototype = new String('true');
const arrayPrototype = new Array();
const objectPrototype = new Object(); // or `new function () {}

从这些元素我们可以创建三种类型的数组。

 // 1) Array of literal-values (boolean, number, string)
const type1 = [ true, 1, "true" ];

// 2) Array of literal-structures (array, object)
const type2 = [ [], {} ];

// 3) Array of prototype-objects (function)
const type3 = [ function () {}, function () {} ];

深拷贝技术依赖于三种数组类型

根据数组中元素的类型,我们可以使用各种技术来进行深拷贝。

深拷贝技术

按元素类型划分的 Javascript 深度复制技术

基准

https://www.measurethat.net/Benchmarks/Show/17502/0/deep-copy-comparison

  • 文字值数组(type1)

The [ ...myArray ] , myArray.splice(0) , myArray.slice() , and myArray.concat() techniques can be used to deep copy arrays with literal values (boolean, number, and仅字符串);其中 slice() 在Chrome中性能最高,spread ... 在Firefox中性能最高。

  • 文字值数组 (type1) 和文字结构 (type2)

JSON.parse(JSON.stringify(myArray)) 技术可用于深度复制文字值(布尔值、数字、字符串)和文字结构(数组、对象),但不能用于原型对象。

  • 所有数组(type1、type2、type3)

    • Lo-dash cloneDeep(myArray)jQuery extend(true, [], myArray) 技术可用于深度复制所有数组类型。其中 Lodash cloneDeep() 技术具有最高的性能。
    • 对于那些避免第三方库的人,下面的自定义函数将深度复制所有数组类型,性能低于 cloneDeep() ,性能高于 extend(true)
 function copy(aObject) {
  // Prevent undefined objects
  // if (!aObject) return aObject;

  let bObject = Array.isArray(aObject) ? [] : {};

  let value;
  for (const key in aObject) {

    // Prevent self-references to parent object
    // if (Object.is(aObject[key], aObject)) continue;

    value = aObject[key];

    bObject[key] = (typeof value === "object") ? copy(value) : value;
  }

  return bObject;
}

所以要回答这个问题…

var arr1 = ['a','b','c'];
var arr2 = arr1;

我意识到 arr2 指的是与 arr1 相同的数组,而不是一个新的独立数组。如何复制数组以获得两个独立的数组?

回答

因为 arr1 是一个文字值数组(布尔值、数字或字符串),您可以使用上面讨论的任何深度复制技术,其中 slice() 和传播 ... 具有最高的性能。

 arr2 = arr1.slice();
arr2 = [...arr1];
arr2 = arr1.splice(0);
arr2 = arr1.concat();
arr2 = JSON.parse(JSON.stringify(arr1));
arr2 = copy(arr1); // Custom function needed, and provided above
arr2 = _.cloneDeep(arr1); // Lo-dash.js needed
arr2 = jQuery.extend(true, [], arr1); // jQuery.js needed

原文由 tim-montague 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题