Why does changing an Array in JavaScript affect copies of the array?

后端 未结 11 1850
礼貌的吻别
礼貌的吻别 2020-11-22 00:16

I\'ve written the following JavaScript:

var myArray = [\'a\', \'b\', \'c\'];
var copyOfMyArray = myArray;
copyOfMyArray.splice(0, 1);
alert(myArray); // aler         


        
相关标签:
11条回答
  • 2020-11-22 00:17

    Cloning objects -

    A loop / array.push produces a similar result to array.slice(0) or array.clone(). Values are all passed by reference, but since most primitive data types are immutable, subsequent operations produce the desired result - a 'clone'. This is not true of objects and arrays, of course, which allow for modification of the original reference (they are mutable types).

    Take the following example:

    const originalArray = [1, 'a', false, {foor: 'bar'}]
    const newArray = [];
    
    originalArray.forEach((v, i) => {
        newArray.push(originalArray[i]);
    });
    
    newArray[0] = newArray[0] + 1;
    newArray[1] = 'b';
    newArray[2] = true;
    newArray[3] = Object.assign(newArray[3], {bar: 'foo'});
    

    The operations run on the newArray indices all produce the desired result, except the final (object), which, because it is copied by reference, will mutate the originalArray[3] as well.

    https://jsfiddle.net/7ajz2m6w/

    Note that array.slice(0) and array.clone() suffers from this same limitation.

    One way to solve this is by effectively cloning the object during the push sequence:

    originalArray.forEach((v, i) => {
        const val = (typeof v === 'object') ? Object.assign({}, v) : v;
        newArray.push(val);
    });
    

    https://jsfiddle.net/e5hmnjp0/

    cheers

    0 讨论(0)
  • 2020-11-22 00:17

    The issue with shallow copy is that all the objects aren't cloned, instead it get reference.So array.slice(0) will work fine only with literal array, but it will not do shallow copy with object array. In that case one way is..

    var firstArray = [{name: 'foo', id: 121}, {name: 'zoo', id: 321}];
    var clonedArray = firstArray.map((_arrayElement) => Object.assign({}, _arrayElement));  
    console.log(clonedArray);
    // [{name: 'foo', id: 121}, {name: 'zoo', id: 321}]  // shallow copy
    
    0 讨论(0)
  • 2020-11-22 00:19

    You can add some error handling depending on your cases and use something similar to the following function to solve the issue. Please comment for any bugs / issues / efficiency ideas.

    function CopyAnArray (ari1) {
       var mxx4 = [];
       for (var i=0;i<ari1.length;i++) {
          var nads2 = [];
          for (var j=0;j<ari1[0].length;j++) {
             nads2.push(ari1[i][j]);
          }
          mxx4.push(nads2);
       }
       return mxx4;
    }
    
    0 讨论(0)
  • 2020-11-22 00:20

    In JS, operator "=" copy the pointer to the memory area of the array. If you want to copy an array into another you have to use the Clone function.

    For integers is different because they are a primitive type.

    S.

    0 讨论(0)
  • 2020-11-22 00:21

    Everything is copied by reference except primitive data types (strings and numbers IIRC).

    0 讨论(0)
  • 2020-11-22 00:26

    Create a filter of the original array in the arrayCopy. So that changes to the new array won't affect original array.

    var myArray = ['a', 'b', 'c'];
    var arrayCopy = myArray.filter(function(f){return f;})
    arrayCopy.splice(0, 1);
    alert(myArray); // alerts ['a','b','c']
    alert(arrayCopy); // alerts ['b','c']
    

    Hope it helps.

    0 讨论(0)
提交回复
热议问题