深入理解JS中的变量以及内存分配问题

427 阅读3分钟

对不同的变量赋相同的值,在内存上是如何实现的?

当你声明一个变量并将其赋值为一个数字时,这个数字本身是一个不可变的值(也称为 "原始值")。 在 JavaScript 中,所有原始值都是在常量池中存储的,因此如果你声明了多个变量,并将它们都赋值为相同的原始值,则它们将指向相同的内存地址。

因此,在你声明的这种情况下,当你声明三个变量 abc,并将它们都赋值为数字 10 时,这三个数字 10 实际上是在内存中的一个地方存储的。

但是,变量本身仍然是独立的。 即使它们指向相同的内存地址,也仍然有三个独立的变量名来引用这个值。 因此,你可以将它们视为三个独立的变量。

例如:

let a = 10;
let b = 10;
let c = 10;

console.log(a); // 10
console.log(b); // 10
console.log(c); // 10

a = 20;

console.log(a); // 20
console.log(b); // 10
console.log(c); // 10

在这种情况下,当你将 a 的值更改为 20 时,变量 a 的值会改变,但是变量 bc 的值不会受到影响,因为它们仍然指向原来的内存地址。

将变量 a 的值更改为 20,在内存上如何实现?

当你将变量 a 的值更改为 20 时,JavaScript 引擎会在内存中为变量 a 分配一块新的内存空间来存储新的值 20。

例如:

let a = 10;

console.log(a); // 10

a = 20;

console.log(a); // 20

在这种情况下,当你首次声明变量 a 时,JavaScript 引擎会在内存中为它分配一块内存空间,并将值 10 存储在该空间中。

当你将 a 的值更改为 20 时,JavaScript 引擎会撤销对原来的内存空间的引用,并为变量 a 分配一块新的内存空间。 新的内存空间中存储的是新的值 20。

因此,当你将变量的值更改为新的值时,JavaScript 引擎会在内存中为这个变量分配一块新的内存空间,并将新的值存储在该空间中。 原来的内存空间将被撤销,并可能在将来被垃圾回收机制回收。

简单数据类型和复杂数据类型的内存分配

简单数据类型(值类型) 是存放在栈里面,里面直接开辟一个空间存放的是值。

image.png

复杂数据类型(引用类型) 首先在栈里面存放地址,用十六进制表示,然后这个地址指向堆里面的数据。

image.png

简单数据类型传参

函数的形参可以看做是一个变量,当我们把一个值类型变量作为参数传给函数的形参时,其实是把变量在栈空间里的值复制了一份给形参,那么在函数内部对形参做任何修改,都不会影响到的外部变量。

image.png

复杂数据类型传参

函数的形参可以看做是一个变量,当我们把引用类型变量传给形参时,其实是把变量在栈空间里保存的堆地址复制给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一个对象。

image.png