将 JavaScript 中的数组复制到另一个数组时:
var arr1 = ['a','b','c'];
var arr2 = arr1;
arr2.push('d'); //Now, arr1 = ['a','b','c','d']
我意识到arr2
引用的是与arr1
相同的数组,而不是一个新的独立数组。如何复制数组以获得两个独立的数组?
用这个:
var newArray = oldArray.slice();
基本上, slice()
操作克隆数组并返回对新数组的引用。另请注意:
对于引用,字符串和数字(而不是实际对象), slice()
对象引用复制到新数组中。原始数组和新数组都引用相同的对象。如果引用的对象发生更改,则更改对新的和原始数组都可见。
字符串和数字等原语是不可变的,因此不可能更改字符串或数字。
在 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 () {}];
根据数组中元素的类型,我们可以使用各种技术进行深度复制。
文字值数组(type1)
[...myArray]
, myArray.splice(0)
, myArray.slice()
和myArray.concat()
技术可用于仅使用文字值(布尔值,数字和字符串)深度复制数组; Spread 运算符[...myArray]
具有最佳性能( https://measurethat.net/Benchmarks/Show/4281/0/spread-array-performance-vs-slice-splice-concat )。
文字值(type1)和文字结构(type2)的数组
JSON.parse(JSON.stringify(myArray))
技术可用于深层复制文字值(布尔值,数字,字符串)和文字结构(数组,对象),但不能用于原型对象。
所有数组(type1,type2,type3)
jQuery $.extend(myArray)
技术可用于深层复制所有数组类型。像Underscore和Lo-dash这样的库为jQuery $.extend()
提供了类似的深拷贝函数,但性能却较低。更令人惊讶的是, $.extend()
性能高于JSON.parse(JSON.stringify(myArray))
技术http://jsperf.com/js-deep-copy/15 。
对于那些回避第三方库(如 jQuery)的开发人员,您可以使用以下自定义函数; 它具有比 $ .extend 更高的性能,并深度复制所有数组。
function copy(aObject) {
if (!aObject) {
return aObject;
}
let v;
let bObject = Array.isArray(aObject) ? [] : {};
for (const k in aObject) {
v = aObject[k];
bObject[k] = (typeof v === "object") ? copy(v) : v;
}
return bObject;
}
题
var arr1 = ['a','b','c'];
var arr2 = arr1;
我意识到 arr2 引用的是与 arr1 相同的数组,而不是一个新的独立数组。如何复制数组以获得两个独立的数组?
回答
因为arr1
是一个文字值数组(布尔值,数字或字符串),所以您可以使用上面讨论的任何深度复制技术,其中扩展运算符...
具有最高性能。
// Highest performance for deep copying literal values
arr2 = [...arr1];
// Any of these techniques will deep copy literal values as well,
// but with lower performance.
arr2 = arr1.slice();
arr2 = arr1.splice(0);
arr2 = arr1.concat();
arr2 = JSON.parse(JSON.stringify(arr1));
arr2 = $.extend(true, [], arr1); // jQuery.js needed
arr2 = _.extend(arr1); // Underscore.js needed
arr2 = _.cloneDeep(arr1); // Lo-dash.js needed
arr2 = copy(arr1); // Custom-function needed - as provided above