堆内存 和 栈内存的简单理解 (未完待续~)

看一个例子:

var a =3;
var b = a;
a=1;
console.log(a,b);
var arr1 = [1,2,3,4];
var arr2 = arr1;
arr1.push(5);
console.log(arr2);

 第一个console.log(a,b) 1 3;

第二个console.log(arr2)  [1,2,3,4,5]

这个问题很奇怪。为什么 b的值变成了 a 原来的值,没有随着a的重新赋值而变化,而 arr2却随着 arr1的变化而变化呢?

原因是;JS值分为两种 :原始值引用值

原始值:String,Undefined、Null、Boolean、Number

引用值:Object  Array Function Date RegExp

所以很显然了,a 和 b 是属于Number类型的,即原始值;而 arr1 和 arr2是属于 Array 类型的,即引用值;

原始值存储在 中;

引用值存储在 中;并且 在 栈 中存储了 堆 的地址;如下图所示:

所以,两种值的存储方式不同,导致了问题的发生。

原始类型中:

var a =3; //在栈中 开辟空间存放3 并且名称为a
var b = a; // 在栈中 开辟空间存放复制 a 的值 并且名称为b
a=1; //在栈中 开辟空间存放3 并且名称为a,原来的地址 a 改为默认的地址,这里是默认的1008,如上图所示;
console.log(a,b);

 引用类型中:

var arr1 = [1,2,3,4];//在堆中 开辟空间存放[1,2,3,4]   并在栈中开辟空间存放 指向对中的地址,栈中名称为 arr1
var arr2 = arr1;// 在栈中开辟空间存放 指向对中的地址,栈中名称为 arr2  这里 arr2存放的堆地址 与 arr1的堆地址相同。
arr1.push(5);
console.log(arr2);

那么如果arr1重新赋值,arr2 会随之 arr1的赋值而改变吗?

其实是不会的,原因是,在堆中,arr1的存储过程中,需要重新再开辟一个空间来存放 arr1最新的一次赋值,当然arr1在栈中指向堆的引用地址就发生了改变,这个时候,arr2在栈中的引用地址 和 arr1的地址不同。所以,这个时候,arr2 不会随着 arr1的赋值而改变。

猜你喜欢

转载自www.cnblogs.com/lixiuming521125/p/10867062.html