<p>当在JavaScript中将一个数组复制到另一个数组时:</p>
<pre class="brush:php;toolbar:false;">var arr1 = ['a','b','c'];
var arr2 = arr1;
arr2.push('d'); // 现在,arr1 = ['a','b','c','d']</pre>
<p>我意识到<code>arr2</code>引用的是与<code>arr1</code>相同的数组,而不是一个新的、独立的数组。我该如何复制数组以获得两个独立的数组?</p>
在Javascript中,深拷贝技术取决于数组中的元素。让我们从这里开始。
三种类型的元素
元素可以是:字面值、字面结构或原型。
// 字面值(类型1) const booleanLiteral = true; const numberLiteral = 1; const stringLiteral = 'true'; // 字面结构(类型2) const arrayLiteral = []; const objectLiteral = {}; // 原型(类型3) const booleanPrototype = new Bool(true); const numberPrototype = new Number(1); const stringPrototype = new String('true'); const arrayPrototype = new Array(); const objectPrototype = new Object(); // 或者 `new function () {}从这些元素中,我们可以创建三种类型的数组。
// 1) 字面值数组(布尔值、数字、字符串) const type1 = [ true, 1, "true" ]; // 2) 字面结构数组(数组、对象) const type2 = [ [], {} ]; // 3) 原型对象数组(函数) const type3 = [ function () {}, function () {} ];深拷贝技术取决于这三种数组类型
根据数组中元素的类型,我们可以使用各种技术进行深拷贝。
深拷贝技术
基准测试
https://www.measurethat.net/Benchmarks/Show/17502/0/deep-copy-comparison
字面值数组(类型1)
可以使用
[ ...myArray ]、myArray.splice(0)、myArray.slice()和myArray.concat()技术来深拷贝只包含字面值(布尔值、数字和字符串)的数组;其中在Chrome中,slice()的性能最高,在Firefox中,扩展运算符...的性能最高。字面值数组(类型1)和字面结构数组(类型2)
可以使用
JSON.parse(JSON.stringify(myArray))技术来深拷贝字面值(布尔值、数字、字符串)和字面结构(数组、对象),但不能拷贝原型对象。所有数组(类型1、类型2、类型3)
cloneDeep(myArray)或 jQuery 的extend(true, [], myArray)技术来深拷贝所有类型的数组。其中Lodash的cloneDeep()技术性能最高。cloneDeep(),但高于extend(true)。function copy(aObject) { // 防止未定义的对象 // if (!aObject) return aObject; let bObject = Array.isArray(aObject) ? [] : {}; let value; for (const key in aObject) { // 防止自引用到父对象 // if (Object.is(aObject[key], aObject)) continue; value = aObject[key]; bObject[key] = (typeof value === "object") ? copy(value) : value; } return bObject; }所以回答这个问题...
问题
答案
因为
arr1是一个包含字面值(布尔值、数字或字符串)的数组,你可以使用上面讨论的任何深拷贝技术,其中slice()和扩展运算符...的性能最高。使用这个:
let oldArray = [1, 2, 3, 4, 5]; let newArray = oldArray.slice(); console.log({newArray});