在JavaScript中按值复制数组
将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()操作克隆数组并将引用返回给新数组。 另请注意:
对于引用,字符串和数字(而不是实际对象),切片将对象引用复制到新数组中。 原始数组和新数组都指向同一个对象。 如果引用的对象发生更改,则这些更改对新数组和原始数组均可见。
字符串和数字等原语是不可变的,因此对字符串或数字的修改是不可能的。
在Javascript中,深度复制技术依赖于数组中的元素。
我们从这里开始。
三种元素
元素可以是:文字值,文字结构或原型。
// Literal values (type1)
var booleanLiteral = true;
var numberLiteral = 1;
var stringLiteral = 'true';
// Literal structures (type2)
var arrayLiteral = [];
var objectLiteral = {};
// Prototypes (type3)
var booleanPrototype = new Bool(true);
var numberPrototype = new Number(1);
var stringPrototype = new String('true');
var arrayPrototype = new Array();
var objectPrototype = new Object(); # or "new function () {}"
从这些元素我们可以创建三种类型的数组。
// 1) Array of literal-values (boolean, number, string)
var type1 = [true, 1, "true"];
// 2) Array of literal-structures (array, object)
var type2 = [[], {}];
// 3) Array of prototype-objects (function)
var type3 = [function () {}, function () {}];
深度复制技术取决于三种阵列类型
根据数组中的元素类型,我们可以使用各种技术进行深度复制。
字面值数组(type1)
可以使用myArray.splice(0)
, myArray.slice()
和myArray.concat()
技术来仅使用文字值(布尔值,数字和字符串)深度复制数组; 其中Slice比Concat具有更高的性能(http://jsperf.com/duplicate-array-slice-vs-concat/3)。
文字值(类型1)和文字结构(类型2)
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(o) {
var output, v, key;
output = Array.isArray(o) ? [] : {};
for (key in o) {
v = o[key];
output[key] = (typeof v === "object" && v !== null) ? copy(v) : v;
}
return output;
}
所以要回答这个问题......
题
var arr1 = ['a','b','c'];
var arr2 = arr1;
我意识到arr2是指与arr1相同的数组,而不是一个新的独立数组。 我如何复制数组来获得两个独立的数组?
回答
由于arr1
是字面值(布尔值,数字或字符串)的数组,因此您可以使用上面讨论的任何深度复制技术,其中slice
具有最高的性能。
// Highest performance for deep copying literal values
arr2 = arr1.slice();
// Any of these techniques will deep copy literal values as well,
// but with lower performance.
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
没有jQuery需要... 工作示例
var arr2 = arr1.slice()
这复制了从开始位置0
到数组末尾的数组。
重要的是要注意,它将按照原始类型(字符串,数字等)的预期工作,并解释引用类型的预期行为。
如果你有一个Reference类型的数组,比如Object
类型。 该数组将被复制,但是两个数组都将包含对同一个Object
的引用。 所以在这种情况下,即使数组实际被复制,看起来数组仍被引用复制。
上一篇: Copying array by value in JavaScript
下一篇: How to get SSL working with Rails, AWS Elastic Beanstalk and Cloudflare