In JS, why does the slice() documentation say it is a shallow copy when it looks like a deep copy?

社会主义新天地 提交于 2019-12-02 11:39:17

问题


According to the docs for Array.prototype.slice() in JavaScript, the slice() method returns a shallow copy of a portion of an array into a new array. It is my understanding that a shallow copy will only copy top level elements in an array and will not copy nested elements. However, when I run a test in my browser console, it sure looks like the slice() method is actually copying the nested elements (deep copying).

Where am I misunderstanding the concept of a deep copy? Please help me clarify as it relates to my exact example.

var array = [1,2,[3,4,[5,6]]];
var array2 = array.slice();

回答1:


In this case the shallow copy means that the nested objects will be pointing to the original values. So by modifying nested objects in the sliced array, you will mutate the original.

It's better to see on the example:

var originalArray = [1, [2, 3], 4];
var slicedArray = originalArray.slice();
var nestedArray = slicedArray[1]; // [2, 3]
nestedArray.push("oh no, I mutated the original array!");
console.log(originalArray); // [1, [2, 3, "oh no, I mutated the original array!"], 4]



回答2:


It's doing a shallow copy. But the values in that shallow copy point to the original arrays/objects, because they're object references.

So let's say we have:

var orig = [ [1] ];

In memory we have:

                    +−−−−−−−−−−−−−+
[orig:Ref22157]−−−−>|   (array)   |
                    +−−−−−−−−−−−−−+        +−−−−−−−−−−−−−+
                    | 0: Ref84572 |−−−−−−−>|   (array)   |
                    +−−−−−−−−−−−−−+        +−−−−−−−−−−−−−+
                                           | 0: 1        |
                                           +−−−−−−−−−−−−−+

Now we do:

var copy = orig.slice();

and have:

                    +−−−−−−−−−−−−−+
[orig:Ref22157]−−−−>|   (array)   |
                    +−−−−−−−−−−−−−+   
                    | 0: Ref84572 |−−−+
                    +−−−−−−−−−−−−−+   |
                                      |
                                      |    +−−−−−−−−−−−−−+
                                      +−−−>|   (array)   |
                    +−−−−−−−−−−−−−+   |    +−−−−−−−−−−−−−+
[copy:Ref54682]−−−−>|   (array)   |   |    | 0: 1        |
                    +−−−−−−−−−−−−−+   |    +−−−−−−−−−−−−−+
                    | 0: Ref84572 |−−−+
                    +−−−−−−−−−−−−−+

Notice how the reference to the nested array (shown here notionally as "Ref84572" but we never see the real values of object references) has been copied, but still refers to the same nested array.

Here's proof it's shallow:

var orig = [ [1] ];
var copy = orig.slice();
console.log("orig[0][0] = " + orig[0][0]);
console.log("copy[0][0] = " + copy[0][0]);
console.log("Setting copy[0][0] to 2");
copy[0][0] = 2;
console.log("orig[0][0] = " + orig[0][0]);
console.log("copy[0][0] = " + copy[0][0]);

Notice that when we modify the state of the nested array, we see that modification no matter which route we take to getting to it (orig[0][0] or copy[0][0]).




回答3:


slice is a shallow copy not because nested values are ignored, but because they contain references to the original arrays, and thus are still linked. For example:

let arr = [1, [2]]
let shallowCopy = arr.slice(0, arr.length);
shallowCopy[1][0] = "foobar";

// will print "foobar", because the nested array is just a reference
console.log(arr[1][0]);


来源:https://stackoverflow.com/questions/48504957/in-js-why-does-the-slice-documentation-say-it-is-a-shallow-copy-when-it-looks

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!