堆内存:分配是动态且不连续
栈内存:只允许一端操作数据,后进先出,速度快,栈内存适合存放生命周期短、占用空间小且固定的数据
原始类型的数据直接存放到栈内存(原始值)
⑴ 当我们定义一个原始类型变量的时候,js 会在栈内存中激活一块内存来储存变量的值(原始值)。
⑵ 当我们更改原始类型变量的值时,实际上会再激活一块新的内存来储存新的值,并将变量指向新的内存空间,而不是改变原来那块内存里的值。
⑶ 当我们将一个原始类型变量赋值给另一个新的变量(也就是复制变量)时,也是会再激活一块新的内存,并将源变量内存里的值复制一份到新的内存里。
--栈内存的原始值一旦确认,不可改变
原始值的比较
当我们比较原始类型的变量时,会直接比较栈内存中的值,只要值相等那么它们就相等。
对象引用(Object references)
1.当我们定义一个引用类型的变量时,JavaScript 会先在堆内存中找到一块合适的地方来储存对象,并激活一块栈内存来储存对象的引用(堆内存地址),最后将变量指向这块栈内存。
所以当我们通过变量访问对象时,实际的访问过程应该是:
变量 -> 栈内存中的引用 -> 堆内存中的值
2.当我们把引用类型变量赋值给另一个变量时,会将源变量指向的栈内存中的对象引用复制到新变量的栈内存中,所以实际上只是复制了个对象引用,并没有在堆内存中生成一份新的对象。
3.而当我们给引用类型变量分配为一个新的对象时,则会直接修改变量指向的栈内存中的引用,新的引用指向堆内存中新的对象。
栈内存中的对象引用是可以被更改的(可变的)
对象的比较(Comparison)
当我们比较引用类型的变量时,实际上是在比较栈内存中的引用,只有引用相同时变量才相等。
对象的深拷贝(Deep copy)
浅拷贝对象是不可靠的。对于任何引用类型的变量,都应该使用深拷贝来复制,除非你很确定你的目的就是复制一个引用。