今天同事突然找我说了一个问题,明明把一个数组复制了,为什么修改的时候两个都会变?
var arr = [1,2,3,4];
var arr2 = arr;
arr.push(5);
console.log(arr) ; // [1,2,3,4,5]
console.log(arr2); // [1,2,3,4,5]
纳尼?? 这个问题不清楚吗,那样的话肯定是不明白原始值与引用值得存储有什么区别,更深层的深度克隆肯定也不知道了。不过现在想想js基础还是很重要的需要在复习一遍了。扯远了,今天还是先讲这个问题是怎么回事。我听到这个问题以后,果断的让他看了下面的代码,问他是不是想要这个效果:
var a = 3;
var b = a;
a = 4
console.log(a); // 4
console.log(b); // 3
得到确认以后,心中大喊“退后,在下要开始装逼了”
咳咳,言归正传,栈和堆对于我们前端来说可以简单的了解一下,栈内存:存储js的原始类型数据(如数字,布尔值)和对象的引入指针(指向堆内存对应的值),先进后出,容易取值。
堆内存:存储js的复杂数据类型例如对象,先进先出,不容易取值。
这样你就明白一件事,原始值与引用值的存储方式是不一样的;原始值会存在栈里,而引用值会把值存在堆里,并且把一个可以找到这个值的一个指针放在栈里。
如果把这个过程理解为去住酒店开房间的话(我去怎么感觉突然就开车了啊),原始值就会直接在栈了开了个房间,把自己的值存入这个房间,引用值就会在堆里开了个房间存入自己的值,再到栈了开个房间放那个堆房间的地址。
而当发生上面赋值的事情,栈里的原始类型就会在开一个房间,把自己的值放入这个新的房间,赋给对方,所以当原始值赋值以后自己改变不会使对方也跟着改变。
var a = 3;
var b = a;
a = 4
console.log(a); // 4
console.log(b); // 3
当引用值赋值时,堆里的房间不会有任何事情发生,而是把栈里的地址复制一份,在栈里开个房间,放入这个复制的地址,所以当引用值赋值以后,两个值都指向堆里房间的内容,当房间内容发生改变的时候,两个值都会改变。
var arr = [1,2,3,4];
var arr2 = arr;
arr.push(5); //向数组的末尾添加一个5,并返回新的长度
console.log(arr) ; // [1,2,3,4,5]
console.log(arr2); // [1,2,3,4,5]
入职不久的小前端从今以后开始自己的技术分享之旅,欢迎建议和批评。