简体   繁体   English

深度复制具有属性的Javascript数组

[英]Deep copy Javascript array with properties

Using .slice() , I can deep copy a Javascript Array of primitive types, for example: 使用.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]

However, If I add a property to arr like so: 但是,如果我像这样添加属性arr

arr.prop1 = 5;

and do the same: 并做同样的事情:

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]

The property values do not carry over to newArr 属性值不会转移到newArr

I have considered not using .slice() and looping over the property values of arr instead, assigning them to newArr , using : 我考虑过不使用.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]

Is this going to be the quickest way to deep copy these arrays with properties? 这是使用属性深度复制这些数组的最快方法吗? Is there in easier or cleaner way I can do this using .slice() or another array method? 是否有更容易或更清洁的方法,我可以使用.slice()或其他数组方法吗? I am doing this operation tens of thousands of times and want it to be as clean and efficient as possible 我正在做这个操作数万次,并希望它尽可能干净和高效

How about using Object.create(proto) 使用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 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create

You are trying to mix an array and object(to make an array behave like an object). 您正在尝试混合数组和对象(使数组的行为类似于对象)。
JavaScript array has numeric indexed items. JavaScript 数组具有数字索引项。
JavaScript object has string indexed items. JavaScript 对象具有字符串索引项。

Arrays have a length property that tells how many items are in the array and is automatically updated when you add or remove items to the array. 数组有一个length属性,用于指示数组中有多少项,并在向数组添加或删除项时自动更新。
But ... 但......

var arr = [1,2,3,4], newArr = arr.slice();
arr.prop1 = 7;

console.log(arr.length);

The output is 4 , though you would expect it to be 5 . 输出是4 ,但你可以期望它是5
But arr.prop1 = 7 does not actually add to the array. 但是arr.prop1 = 7实际上并没有添加到数组中。
Setting a string parameter adds to the underlying object . 设置字符串参数会添加到基础对象
The length property is only modified when you add an item to the array, not the underlying object. 只有在将项添加到数组而不是基础对象时,才会修改length属性。
The expression newArr = arr.slice() assigns a new array to newArr , so it remains an array and behaves like a pure array. 表达newArr = arr.slice()分配一个新的数组newArr ,因此它仍然是一个阵列,并且表现得像一个阵列。

The property values do not carry over to newArr 属性值不会转移到newArr

If you still want to proceed using mixed numeric/string indexed sequences, cloning them, try using Object.assign() function. 如果您仍想继续使用混合数字/字符串索引序列,克隆它们,请尝试使用Object.assign()函数。 This should be the easiest way for your case: 对于您的情况,这应该是最简单的方法:

The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. Object.assign()方法用于将所有可枚举自身属性的值从一个或多个源对象复制到目标对象。

console.log(Object.assign(newArr, arr));

The output: 输出:

[1, 2, 3, 4, prop1: 7]

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM