Copy array by value

2018-12-30 23:21发布

When copying an array in JavaScript to another array:

var arr1 = ['a','b','c'];
var arr2 = arr1;
arr2.push('d');  //Now, arr1 = ['a','b','c','d']

I realized that arr2 refers to the same array as arr1, rather than a new, independent array. How can I copy the array to get two independent arrays?

30条回答
余欢
2楼-- · 2018-12-31 00:02

Quick Examples:

  1. If elements in the array are primitive types (string, number, etc.)

var arr1 = ['a','b','c'];
// arr1 and arr2 are independent and primitive elements are stored in 
// different places in the memory
var arr2 = arr1.slice(); 
arr2.push('d');
console.log(arr1); // [ 'a', 'b', 'c' ]
console.log(arr2); // [ 'a', 'b', 'c', 'd' ]

  1. If elements in the array are object literals, another array ({}, [])

var arr1 = [{ x: 'a', y: 'b'}, [1, 2], [3, 4]];
// arr1 and arr2 are independent and reference's/addresses are stored in different
// places in the memory. But those reference's/addresses points to some common place
// in the memory.
var arr2 = arr1.slice(); 
arr2.pop();      // OK - don't affect arr1 bcos only the address in the arr2 is
                 // deleted not the data pointed by that address
arr2[0].x = 'z'; // not OK - affect arr1 bcos changes made in the common area 
                 // pointed by the addresses in both arr1 and arr2
arr2[1][0] = 9;	 // not OK - same above reason

console.log(arr1); // [ { x: 'z', y: 'b' }, [ 9, 2 ], [ 3, 4 ] ]
console.log(arr2); // [ { x: 'z', y: 'b' }, [ 9, 2 ] ]

  1. Solution for 2: Deep Copy by element by element

var arr1 = [{ x: 'a', y: 'b'}, [1, 2], [3, 4]];
arr2 = JSON.parse(JSON.stringify(arr1));
arr2.pop();	  // OK - don't affect arr1
arr2[0].x = 'z';  // OK - don't affect arr1
arr2[1][0] = 9;	  // OK - don't affect arr1

console.log(arr1); // [ { x: 'a', y: 'b' }, [ 1, 2 ], [ 3, 4 ] ]
console.log(arr2); // [ { x: 'z', y: 'b' }, [ 9, 2 ] ]

查看更多
梦寄多情
3楼-- · 2018-12-31 00:03

Important!

Most of answers here works for particular cases.

If you don't care about deep/nested objects and props use (ES6):

let clonedArray = [...array]

but if you want to do deep clone use this instead:

let cloneArray = JSON.parse(JSON.stringify(array))


For lodash users:

let clonedArray = _.clone(array) documentation

and

let clonedArray = _.cloneDeep(array) documentation

查看更多
无与为乐者.
4楼-- · 2018-12-31 00:03

There's the newly introduced Array.from, but unfortunately, as of the time of this writing it's only supported on recent Firefox versions (32 and higher). It can be simply used as follows:

var arr1 = [1, 2, 3];
console.log(Array.from(arr1)); // Logs: [1, 2, 3]

Reference: Here

Or Array.prototype.map may be used with an identity function:

function identity(param)
{
    return param;
}

var arr1 = [1, 2, 3],
    clone = arr1.map(identity);

Reference: Here

查看更多
与君花间醉酒
5楼-- · 2018-12-31 00:04

Some of mentioned methods work well when working with simple data types like number or string, but when the array contains other objects these methods fail. When we try to pass any object from one array to another it is passed as a reference, not the object.

Add the following code in your JavaScript file:

Object.prototype.clone = function() {
    var newObj = (this instanceof Array) ? [] : {};
    for (i in this) {
        if (i == 'clone') 
            continue;
        if (this[i] && typeof this[i] == "object") {
            newObj[i] = this[i].clone();
        } 
        else 
            newObj[i] = this[i]
    } return newObj;
};

And simply use

var arr1 = ['val_1','val_2','val_3'];
var arr2 = arr1.clone()

It will work.

查看更多
千与千寻千般痛.
6楼-- · 2018-12-31 00:04

I personally think Array.from is a more readable solution. By the way, just beware of its browser support.

//clone
let x = [1,2,3];
let y = Array.from(x);

//deep clone
let clone = arr => Array.from(arr,item => Array.isArray(item) ? clone(item) : item);
let x = [1,[],[[]]];
let y = clone(x);
查看更多
流年柔荑漫光年
7楼-- · 2018-12-31 00:05

You could use ES6 with spread Opeartor, its simpler.

arr2 = [...arr1];

There are limitations..check docs Spread syntax @ mozilla

查看更多
登录 后发表回答