JS高级:代码在堆栈中执行过程

146 阅读2分钟

电脑内存分为虚拟内存和物理内存,代码运行都是在虚拟内存中去执行的。

let a = {n:1}
let b = a
a.x = a = {n:2}
console.log(a.x)
console.log(b)

首先浏览器在执行以上代码的时候,首先会从计算机的虚拟内存中分配两块内存:堆、栈

  • 栈 Stack(ECStack]):作用主要是有两个:供代码执行、存储声明的变量和原始值类型的数据
  • 堆 Heap:作用只有一个存储对象类型的值

默认在堆内存中,开辟一个空间地址为16进制的空间称为全局对象GO(Global Object),全局对象默认存储的是浏览器为JS提供的内置API,例如 setTimeout\setInterval\requestAnimation

接下来会执行JS代码

首先会在栈内存中产生一个全局的执行上下文(ECG),供全局代码执行的环境。 在代码的执行过程中会声明变量,所以需要一个存放变量的地方:变量对象 VO/AO。

首先执行的是 let a = {n:1}

  1. 先创建值:值是一个对象,则会在堆中开辟一块空间(假如为 0x001)
  2. 再将a放在VO中存储
  3. 最后让VO中的变量与值关联。a指向0x001

图示如下:

截屏2022-10-17 22.39.41.png

执行第二句: let b = a;

  1. 创建值,这里因为值就是a,所以值就是 0x001
  2. 将b放在VO中存储
  3. 关联

截屏2022-10-17 22.45.06.png

执行第3句:a.x = a = {n:2}

在JS中,连续赋值的时候,正常情况下是从右往左处理,例如 let a = b = 1, 先执行 b = 1,再执行let a = b,但是如果遇到成员访问则优先级更高则先执行。所以第三句的执行顺序是:

  1. 还是先创建值,在堆中创建对象 {n:2} 0x002
  2. 成员访问优先级更高,执行 a.x = 0x002
  3. 再执行a = 0x002

截屏2022-10-17 22.59.50.png

所以打印答案也就一目了然了

a.x -> undefined

b -> {n:1,x:{n:2}}