以下代码输出到控制台的原因是什么?
var arr1 = "john".split('');
var arr2 = arr1.reverse();
var arr3 = "jones".split('');
arr2.push(arr3);
console.log("array 1: length=" + arr1.length + " last=" + arr1.slice(-1));
console.log("array 2: length=" + arr2.length + " last=" + arr2.slice(-1));
Out Put将是: "数组1:长度= 5最后= j,o,n,e,s" "数组2:长度= 5最后= j,o,n,e,s"
以下是与此问题一起发布的答案。但是,我不明白这是什么javascript原则或规则?
" reverse()方法返回对数组本身的引用(即,在本例中为arr1)。因此,arr2只是对arr1的引用(而不是副本)。因此,当对arr2做任何事情时(即,当我们调用arr2.push(arr3);)时,arr1也将受到影响,因为arr1和arr2只是对同一对象的引用。"
答案 0 :(得分:5)
让我们逐行分解:
var arr1 = "john".split('');
arr1现在指向数组['j','o','h','n']。
var arr2 = arr1.reverse();
arr1和arr2现在指向同一个数组,即['n','h','o','j']。
var arr3 = "jones".split('');
arr3现在指向数组['j','o','n','e','s']。
arr2.push(arr3);
arr2和arr1现在都指向数组['n','h','o','j',['j','o','n','e','s'] ]。请注意,arr3的元素未附加到arr1和arr2指向的数组。而是将整个数组添加为单个元素。
console.log("array 1: length=" + arr1.length + " last=" + arr1.slice(-1));
记录arr1的长度,即5('n','h','o','j'和第二个数组)。 arr1.slice(-1)获取arr1数组的最后一个元素,即包含'j','o','n','e','s'的数组。最后一行重复了这一点,但是使用了arr2,它只是对arr1的同一个数组的另一个引用。
答案 1 :(得分:0)
我认为原因是将arr1.reverse()分配给arr2就像将它绑定到它一样。你没有创建一个新的arr1实例,而是使用相同的数组。
所以
arr2.push(arr3);
等同于
arr1.reverse().push(arr3)
当你以那种方式看待它时自然会影响arr1
我可能错了,但这就是我认为正在发生的事情
答案 2 :(得分:0)
此代码中需要注意的是行号。 2
var arr2 = arr1.reverse();
这段代码说反转存储在内存中的数组[arr1指向的]并且arr2也指向同一个数组。
所以,你最终还是有一个参考[arr2]给arr1引用的数组。
然后通过这个新的引用arr2更新相同的数组。
arr2.push(arr3);
所以,一直有一个数组存储在内存中,两个引用[arr1和arr2]相同。您可以通过任何引用更新存储在该内存中的值,并且所有引用都将反映更改,因为它们指向相同的内存。
答案 3 :(得分:-1)
执行以下操作:
var arr1 = "john".split(''); //splits into j, o, h, n
var arr2 = arr1.reverse(); // reverses the array to n, h, o, j
var arr3 = "jones".split(''); // splits into j, o, n, e, s
arr2.push(arr3); // adds arr3 to the end of arr2
console.log("array 1: length=" + arr1.length + " last=" + arr1.slice(-1));
console.log("array 2: length=" + arr2.length + " last=" + arr2.slice(-1));