将JavaScript中的数组复制到另一个数组时:
var arr1 = ['a','b','c'];
var arr2 = arr1;
arr2.push('d'); //Now, arr1 = ['a','b','c','d']
我意识到arr2指的是与arr1相同的数组,而不是一个新的独立数组。如何复制阵列以获得两个独立的阵列?
将JavaScript中的数组复制到另一个数组时:
var arr1 = ['a','b','c'];
var arr2 = arr1;
arr2.push('d'); //Now, arr1 = ['a','b','c','d']
我意识到arr2指的是与arr1相同的数组,而不是一个新的独立数组。如何复制阵列以获得两个独立的阵列?
当前回答
在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 () {} ];
深度复制技术取决于三种阵列类型
根据数组中元素的类型,我们可以使用各种技术进行深度复制。
深度复制技术
基准
https://www.measurethat.net/Benchmarks/Show/17502/0/deep-copy-comparison
文字值数组(类型1)[…myArray]、myArray.splice(0)、myArrax.slice()和myArray.concat()技术可用于深度复制仅具有文字值(布尔值、数字和字符串)的数组;其中slice()在Chrome中具有最高的性能,并且扩展。。。在Firefox中具有最高的性能。文本值(类型1)和文本结构(类型2)的数组JSON.parse(JSON.stringify(myArray))技术可用于深度复制文本值(布尔值、数字、字符串)和文本结构(数组、对象),但不能复制原型对象。所有数组(类型1、类型2、类型3)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()和spread。。。具有最高的性能。
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
其他回答
这里有一个变体:
var arr1=['a', 'b', 'c'];
var arr2=eval(arr1.toSource());
arr2.push('d');
console.log('arr1: '+arr1+'\narr2: '+arr2);
/*
* arr1: a,b,c
* arr2: a,b,c,d
*/
在我的特殊情况下,我需要确保阵列保持完整,所以这对我来说很有用:
// Empty array
arr1.length = 0;
// Add items from source array to target array
for (var i = 0; i < arr2.length; i++) {
arr1.push(arr2[i]);
}
以下是如何对可变深度的基元数组执行此操作:
// If a is array:
// then call cpArr(a) for each e;
// else return a
const cpArr = a => Array.isArray(a) && a.map(e => cpArr(e)) || a;
let src = [[1,2,3], [4, ["five", "six", 7], true], 8, 9, false];
let dst = cpArr(src);
https://jsbin.com/xemazog/edit?js安慰
使用此项:
让oldArray=[1,2,3,4,5];let newArray=oldArray.slice();console.log({newArray});
基本上,slice()操作克隆数组并返回对新数组的引用。
还应注意:
对于引用、字符串和数字(而不是实际对象),slice()将对象引用复制到新数组中。原始数组和新数组都引用同一对象。如果引用的对象发生更改,则这些更改对新阵列和原始阵列都可见。
字符串和数字等基元是不可变的,因此不可能更改字符串或数字。
如果您在ECMAScript 6环境中,使用Spread Operator,您可以这样做:
var arr1=[‘a’,‘b’,‘c’];var arr2=[…arr1]//复制arr1arr2.推('d');控制台日志(arr1)控制台日志(arr2)<script src=“http://www.wzvang.com/snippet/ignore_this_file.js“></script>