通过动画了解JS中的ECStack、EC、VO 和 AO

884 阅读4分钟

前言

今天通过探讨下面 JS 代码是如何执行的,来了解 JS 中一些不常见但很重要的知识点

var x = [12, 23]
function fn(y) {
   y[0] = 100;
   y = [100]
   y[1] = [200]
}
fn(x)
console.log(x)

相信大家只用了 1s 就知道答案了,让我们探讨下代码背后是如何执行的吧

执行过程

1、ECStack 、GO、EC、VO、AO

浏览器会在计算机内存中分配一块内存,专门用来供代码执行的栈内存,称作执行环境栈(ECStack) 同时会创建一个全局对象(GO),将内置的属性方法( isNaNsetIntervalsetTimeout... )存放到一块单独的堆内存空间,并且使用 window  指向全局对象

在执行代码前,还需要创建一个全局执行上下文( EC(G) ), 创建完成后,进入到栈内存中去执行( 进栈 ); 在当前全局执行上下文中,因为会创建很多变量并且赋值,所以会创建一个变量对象 VO(Variable Object) 来进行保存,在函数私有上下文中的变量对象叫做 活动对象 AO(Activation Object) (ps: 每个执行上下文都有一个单独的变量对象)

总结下这些陌生不常见的名词

  • 执行环境栈ECStack ( Execution Context Stack ):专门用来供代码执行的栈内存
  • 全局对象GO(Global Object):存放内置的属性方法,window 指向
  • 全局执行上下文EC(G) ( Execution Context(G) ):页面加载后进栈、销毁后出栈
  • 变量对象VO (Variable Object):存放当前执行上下文中创建的变量和值
  • 活动对象AO (Activation Object):函数私有上下文中的变量对象

js_001.gif

2、全局代码执行

当一切准备就绪,就开始从上到下执行代码 (ps: 执行前还会涉及变量提升的问题,这里不进行展开)

var x = [12, 23]

js 在解析这段代码时,会按照以下 3 个步骤

  • 先创建一个值 [12, 23]
  • 再创建一个变量 x
  • 最后将变量与值进行关联

当创建的值是引用类型时,会在堆内存中开辟新的内存空间用了保存值,创建完成后,会将堆内存地址(通常是 16 进制 )保存到栈内存中; 如果创建的值是基本类型时,会直接保存到栈内存中

js_002.gif 继续向下执行,

function fn(y) {
   y[0] = 100;
   y = [100]
   y[1] = [200]
}

函数也是属于引用类型,也需要开辟堆内存空间进行保存,不同于数组和对象保存的是键值对,JS会将函数体通过字符串包裹进行保存,同时也会保存函数相关的属性,例如 函数名 name: fn形参个数length: 1 等。同时,更重要的是,创建函数的时候,就定义了函数的作用域,也就是 等于当前创建函数的执行上下文。 在这个例子中,函数fn 的作用域就是全局执行上下文,标识为 [[scope]]:EC(G)

js_003.gif 在函数创建好后,继续向下执行

fn(x)

通过上面的动图了解到,fn 和 x 都指向堆内存地址,所以,fn(x) 相当于 AAAFFF000(AAAFFF111) , 在执行函数体代码之前,我们需要知道的是:

  • 每次函数执行,都会创建一个函数私有执行上下文,创建完之后,需要进入到栈内存中去执行,此时,执行栈中的全局执行上下文就会被压入到栈底(压栈)

  • 同时,需要创建一个活动对象 AO 存放当前函数执行上下文中创建的变量和值等

js_004.gif

再完成函数执行上下文入栈后,接下来会做以下几件事

  1. 初始化作用域链 scopeChain: 作用域链通常标记为 <当前执行上下文, 函数创建时的作用域> ,而作用域链是为了函数执行过程中,当活动对象中不存在某个变量时,会沿着作用域链向上找到
  2. 初始化 this 指向 : 本例子中,this 等于 window
  3. 初始化实参集合 arguments
  4. 形参赋值 y = x = AAAFFF111
  5. 执行函数体 紧接着就是执行函数体内容,在执行完成后,当前函数的执行上下文就会出栈,退出执行栈,而被压入栈底的全局执行上下文又被推到了栈顶,此时会继续执行全局上下文中的代码

js_005 (1).gif 至此,代码执行结束,最终输出的 x 是 [100, 23]

总结

以上,就是本篇内容的全部内容了,如有歧义,欢迎大家留言交流 (Ps: 动图使用 keynote 制作,制作不易,大家多多点赞 )