一个面试题,不明白这其中的过程

直接上代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test</title>
</head>
<body>
    <button>test</button>
    <script>
        var arr1 = new Array();  
        var arr2 = new Array();
        arr1 = [1,2,3,4,5];
        var button = document.getElementsByTagName('button')[0];
        button.onclick = function(){
            console.log(arr1);
            arr2.push(arr1);
            console.log(arr2);            
            console.log(arr2[0]);
            arr1.pop();         
            console.log(arr1);
            console.log(arr2[0]);
        }              
    </script>
</body>
</html>

我测试的结果:
图片描述

有2个不明白的地方:
1.箭头指的地方为什么没有显示出5?
2.从头到尾没有弹出arr2,为什么arr2会随着arr1的变化而变化?

解决方案?
如果我只是想在操作arr1的时候,不影响arr2,有没有什么办法?

阅读 2.6k
4 个回答
console.log(arr1);   //line 1
arr2.push(arr1);    //line 2
console.log(arr2);  //line 3          
console.log(arr2[0]); //line 4
arr1.pop();    //line5     
console.log(arr1); //line 6
console.log(arr2[0]); //line 7

回答
1.箭头指的地方为什么没有显示出5?
执行line 3的时候,控制台打出 [Array[5]] 是正确的,但是当你点击之前的小箭头展开[]中具体内容的时候,所有语句都执行完,arr1的最后一个元素被你pop()了所以此时只有4个items

2.从头到尾没有弹出arr2,为什么arr2会随着arr1的变化而变化?
因为arr2[0]内存指向的就是arr1,所以arr1变了,arr2[0]也会跟着变

解决方案?
使用克隆大法,把arr1克隆一份再赋值给arr2[0]

  1. 纯粹是控制台在接受console.log时,仍然是js执行环境,所以对引用类型的对象不具备时效性。如果你把第一个console换成console.log(arr1.join(''));,那么12345就都显示出来了。

  2. 还是因为array是引用类型的缘故,想解决好办,把arr2.push(arr1);改成arr2.push([].concat(arr1));

其实通篇都是在考你对象的引用类型带来的副作用,多努力哦,祝你成功!

1.箭头指的地方为什么没有显示出5?

    是因为 arr2.push(arr1);是将arr1作为一个整体,追加成了arr2里的一个数组元素,如果不明白可以给arr2设置初始值,可以更明白,例如:  var arr2 = new Array(9,10);arr2.push(arr1);
        console.log(arr2);
        

2.从头到尾没有弹出arr2,为什么arr2会随着arr1的变化而变化?
明白第一个之后,第二个就跟着明白了。

你可以打断点看pop()没走的时候是有5的。2随着1变化,证明push时候存放的是指针。

Array.prototype.push.apply(arr2, arr1);
//arr2.push(arr1);

替换下 看看接口。不过2的格式跟之前不同

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题