JS执行上下文
初始化全局对象 Global Object(GO)
◼ js引擎会在执行代码之前,会在(堆内存)中创建一个全局对象:Global Object(GO)
该对象所有的作用域(scope)都可以访问;
里面会包含Date、Array、String、Number、setTimeout、setInterval等等;
其中还有一个window属性指向自己
执行上下文(Execution Contexts )
◼ js引擎内部有一个执行上下文栈(Execution Context Stack,简称ECS),它是用于执行代码的调用栈。
◼ 那么现在它要执行谁呢?执行的是全局的代码块:
全局的代码块为了执行会构建一个Global Execution Context(GEC);
GEC会被放入到ECS中执行;
◼ GEC被放入到ECS中里面包含两部分内容:
第一部分:在代码执行前,在parser转成AST的过程中,会将全局定义的变量、函数等加入到GlobalObject中,但是并不会赋值;
✓ 这个过程也称之为变量的作用域提升(hoisting)
第二部分:在代码执行中,对变量赋值,或者执行其他的函数;
认识VO对象(Variable Object)
◼ 每一个执行上下文会关联一个VO(Variable Object,变量对象),变量和函数声明会被添加到这个VO对象中。
◼ 当全局代码被执行的时候,VO就是GO对象了
全局代码执行过程
全局代码执行:
创建一个执行上下文中会关联一个VO对象-----> 1.全局代码在执行之前会创建一个全局对象GO并且与VO关联--->2.GO记录的是所有被定义的全局变量的名称,他们的值都是undefined,并且全局对象里的函数如果有内容会优先创建一个函数的对象--->3.给变量进行赋值或者执行其他的函数
函数代码执行过程
在执行的过程中执行到一个函数时,就会根据函数体创建一个函数执行上下文(Functional Execution Context,简称FEC),并且压入到EC Stack中。
◼ 因为每个执行上下文都会关联一个VO,那么函数执行上下文关联的VO是什么呢?
当进入一个函数执行上下文时,会创建一个AO对象(Activation Object);
这个AO对象会使用arguments作为初始化,并且初始值是传入的参数;
这个AO对象会作为执行上下文的VO来存放变量的初始化;
函数执行:
创建一个执行上下文VO----->创建一个AO对象,VO对象关联AO对象保存变量的名称,并且赋值为undefined---->AO对象使用argument作为初始化保存传入的形参---->为变量进行赋值---->执行完成会弹出--->继续执行全局执行上下文
作用域和作用域链
◼ 当进入到一个执行上下文时,执行上下文也会关联一个作用域链(Scope Chain)
作用域链是一个对象列表,用于变量标识符的求值;
当进入一个执行上下文时,这个作用域链被创建,并且根据代码类型,添加一系列的对象;
!!!作用域链是在定义的位置一层层往上找的和调用的位置没关系