使用.slice()
,我可以深层复制原始类型的Javascript数组,例如:
var arr = [1,2,3,4];
var newArr = arr.slice();
newArr.push(5);
console.log(arr); // [1,2,3,4]
console.log(newArr); // [1,2,3,4,5]
但是,如果我向arr
添加属性,那么:
arr.prop1 = 5;
并做同样的事情:
var arr = [1,2,3,4];
arr.prop1 = 8;
arr.prop2 = 9;
var newArr = arr.slice();
newArr.push(5);
console.log(arr); // [1, 2, 3, 4, prop1: 9, prop2: 8]
console.log(newArr); // [1, 2, 3, 4, 5]
属性值不会延续到newArr
我考虑过不使用.slice()
并循环使用arr
的属性值,而是将它们分配给newArr
,使用:
for (var key in arr) {
if (arr.hasOwnProperty(key)) {
newArr[key] = arr[key];
}
}
console.log(arr); // [1, 2, 3, 4, prop1: 9, prop2: 8]
console.log(newArr); // [1, 2, 3, 4, 5, prop1: 9, prop2: 8]
这是使用属性深度复制这些数组的最快方法吗?我可以使用.slice()
或其他数组方法以更简单或更清晰的方式执行此操作吗?我正在做这个操作数万次,并希望它尽可能干净和高效
答案 0 :(得分:2)
如何使用Object.create(proto)
var arr = [1,2,3,4];
arr.prop1 = 8;
arr.prop2 = 9;
var newArr = Object.create(arr);
newArr.prop1 = 12;
console.log(arr.prop1) // 8
console.log(newArr.prop1) // 12
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
答案 1 :(得分:2)
您正在尝试混合数组和对象(使数组的行为类似于对象)
JavaScript 数组具有数字索引项目
JavaScript 对象具有字符串索引项。
数组具有 length 属性,该属性可以告知数组中有多少项,并在向数组中添加或删除项时自动更新。
但是......
var arr = [1,2,3,4], newArr = arr.slice();
arr.prop1 = 7;
console.log(arr.length);
输出为4
,但您希望它为5
。
但arr.prop1 = 7
实际上并未添加到数组中。
设置字符串参数添加到底层对象
仅当您向数组添加项而不是基础对象时,才会修改 length 属性。
表达式newArr = arr.slice()
将新数组分配给newArr
,因此它仍然是一个数组,其行为类似于纯数组。
属性值不会转移到newArr
如果您仍想继续使用混合数字/字符串索引序列,克隆它们,请尝试使用Object.assign()
函数。对于你的情况,这应该是最简单的方法:
Object.assign()方法用于复制all的值 枚举从一个或多个源对象到目标的自有属性 对象
console.log(Object.assign(newArr, arr));
输出:
[1, 2, 3, 4, prop1: 7]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign