上下文与执行栈

Posted 纸 飞机

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了上下文与执行栈相关的知识,希望对你有一定的参考价值。

js引擎运行一段<script>大致分两大阶段

一、语法解析阶段

js代码块加载完毕之后进行,主要有:

1.词法分析:将代码以token (关键字,操作符等有意义的最小单元)为单位切割成一个个独立的单元后组成tokens列表。例 如 let a = 10 被分成 let, a,=,10。

2 .语法分析:将tokens列表转换成抽象语法树结构(AST)。同时,验证语法, 如出现语法错误 ,则抛出异常Syntax error。

3.代码生成:根据AST生成机器识别的字节码。

二、运行阶段(重点)

A、执行上下文(Execution Context)

又叫执行环境,即当前代码执行时所在的环境。分全局上下文和函数上下文。由于js 代码是在上下文中运行的,所以需要先创建上下文再在其中执行代码,创建阶段发生在代码正式执行的前一瞬间,之后代码执行完毕该上下文会被回收。一个上下文的生命周期包括了创建 ,执 行 , 段。具体过程如下:

1.创建执行上下文:

该阶段为正式执行代码做一些前期准备工 作。主要包括:

a.创建变量对象( variable object)

保存该环境定义的所有变量和函数的声明。首先初始化函数的参数arguments, 然后提升函数声明和变量声明。全局环境的变量对象叫GO (Global Object,全局对象,等于window)。函数环境的变量对象激活后即代码执行后又叫AO (Activetion Object,活动对象)。

b.创建作用域链( scope chain)

作用域链是由各个环境的变量对象的指针 组成的数组scope,第一项永远是当前上下文的变量对象,其后是其外部上下文的变量对象,最后一项永远是全局上下文的变量对象window,这样保证了当前执行环境 对其外部环境变量的查找。

具体过程是创建环境时先复制父级的[[scope]]属性到当前上下文下,形成当前环境的作用域链,然后将当前环境的变量对象推入作用域链的最前端。

c.确定this的指向

全局环境中,this指向window。函数环境下的this指向根据执行环境和执行方法确定。

2.代码正式执行:

在当前所在的执行上下文里按顺序执行代码,如赋值,函数调用,其他语句执行等,也包括Event Loop的异步执行机制, 遇到异步代码放入web apis。

3.回收执行上下文:

代码执行完毕后当前执行环境出栈并等待引擎的垃圾回收机制回收。

B、执行栈(Execution stack)

1 .或称调用栈(Call stack), 一段js程序中一般会创建多个执行上下文,JS运行前会创建一个执行栈来储存并管理所有的上下文。每调用一个函数都会创建相应的执行上下文并推入栈中。栈底是全局执行上下文,栈顶是当前函数执行上下文,遵循栈结构先进后出的原则。

2 .引擎首次读取脚本时会创建一个全局的执行上下文并且压入当前执行栈,处于栈底。然后执行全局代码。

3 .当执行流遇到函数调用时,会创建一个新的属于函数自己的执行上下文,并添加到栈中,处于栈顶。然后执行函数内部代码,完毕后将该上下文从栈中移出销毁。 将控制权交给下一个(之前的)执行环境。

4 .当整体代码都执行完毕,栈里只剩全局 上下文,关闭浏览器窗口则移出全局上下文。

5 . 一段整体js是分在执行栈中的不同上下 文中执行完成的。而且执行栈有大小,当入栈的上下文超过一定数量,会出现栈溢出问题stack overflow。

let a = 1;
fn1(){
    console.log('fn1');
    fn2();
}
fn2() {
    console.Iog('fn2');
)
fn1();
console.log('Global');

 

 

以上是关于上下文与执行栈的主要内容,如果未能解决你的问题,请参考以下文章

上下文与执行栈

理解运用JS的闭包高阶函数柯里化

278 执行上下文执行上下文栈:变量提升与函数提升,执行上下文,执行上下文栈,全局执行上下文,函数执行上下文,练习题

js基础梳理-究竟什么是执行上下文栈(执行栈),执行上下文(可执行代码)?

前端面试题(执行上下文与执行上下文栈作用域与作用域链闭包内存溢出与内存泄露)

方法与对象内存分析