JavaScript的执行过程(深入执行上下文、GO、AO、VO和VE等概念)

引言:在代码执行时,关于栈内存和堆内存的内存图流程,由于markdown不支持放图片,所以可以私信找我拿

1.全局对象的创建
  • JS引擎会在执行代码之前,也就是解析代码时,会在我们的堆内存创建一个全局对象:Global Object(简称GO)

  • JS引擎内部在解析代码时,会创建一个全局对象(伪代码如下):

  • 所有的**作用域(scope)**都可以访问该全局对象;

  • 对象里面会包含一些全局的方法和类,像Math、Date、String、Array、setTimeout等等;

  • 其中有一个window属性是指向该全局对象自身的;

  • 该对象中会收集我们全局定义的变量,并设置成undefined;

  • 全局对象是非常重要的,我们平时之所以能够使用这些全局方法和类,都是在这个全局对象中获取的;

2.执行全局代码
  • 在栈内存中创建全局执行上下文

  • 将VO指向到GO上

  • 从上往下开始执行全局代码,依次对GO对象中的全局变量进行赋值

3.执行函数代码
  • 在执行的过程中遇到函数,就会根据函数体创建一个函数执行上下文(Functional Execution Context,简称FEC),并且加入到执行上下文栈(ECS)中。

  • 函数执行上下文(FEC)包含三部分内容:

  • AO:在解析函数时,会创建一个Activation Objec(AO)

  • 作用域链:由函数VO和父级VO组成,查找是一层层往外层查找;

  • this指向:this绑定的值,在函数执行时确定;

  • 其实全局执行上下文(GEC)也有自己的作用域链和this指向,只是它对应的作用域链就是自己本身,而this指向为window。

  • 每次调用函数,都会构建一个新的AO

4.变量环境和记录(VO)
  • 在早期ECMA的版本规范中:每一个执行上下文会被关联到一个变量环境(Variable Object,简称VO),在源代码中的变量和函数声明会被作为属性添加到VO中。对应函数来说,参数也会被添加到VO中。

  • 也就是上面所创建的GO或者AO都会被关联到变量环境(VO)上,可以通过VO查找到需要的属性;

  • 规定了VO为Object类型,上文所提到的GO和AO都是Object类型;

  • 在最新ECMA的版本规范中:每一个执行上下文会关联到一个变量环境(Variable Environment,简称VE),在执行代码中变量和函数的声明会作为**环境记录(Environment Record)**添加到变量环境中。对于函数来说,参数也会被作为环境记录添加到变量环境中。

  • 也就是相比于早期的版本规范,对于变量环境,已经去除了VO这个概念,提出了一个新的概念VE;

  • 没有规定VE必须为Object,不同的JS引擎可以使用不同的类型,作为一条环境记录添加进去即可;

  • 虽然新版本规范将变量环境改成了VE,但是JavaScript的执行过程还是不变的,只是关联的变量环境不同,将VE看成VO即可;

5.作用域和作用域链
  • 函数在执行前就已经确定了其父级作用域,与函数在哪执行没有关系,以函数声明的位置为主;

  • 执行代码查找变量属性时,会沿着作用域链一层层往上查找(沿着scope chain往上找),如果一直找到全局对象中还没有该变量属性,就会报错未定义;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值