关于前端:前端百题斩010通俗易懂的JavaScript执行上下文

12次阅读

共计 2188 个字符,预计需要花费 6 分钟才能阅读完成。

写该系列文章的初衷是“让每位前端工程师把握高频知识点,为工作助力”。这是前端百题斩的第 10 斩,心愿敌人们关注公众号“执鸢者”,用常识武装本人的头脑。

JavaScript 规范吧一段代码(包含函数)执行所需的所有信息定义为“执行上下文”(可了解为以后代码的执行环境,同一个函数在不同的环境中执行,会因拜访的数据不同产生不一样的后果),其是执行的基础设施。执行上下文蕴含的内容有很多,上面从类型、蕴含内容、生命周期、执行过程、论断来进行论述。

10.1 类型

执行上下文次要分为三类:全局执行上下文、函数执行上下文、eval 函数执行上下文。

  1. 全局执行上下文

当 JavaScript 执行全局代码的时候,会编译全局代码并创立全局执行上下文,而且在整个页面的生存周期内,全局执行上下文只有一份。

  1. 函数执行上下文

当调用一个函数的时候,函数体内的代码会被编译,并创立函数执行上下文,个别状况下,函数执行完结之后,创立的函数执行上下文会被销毁。

  1. eval 执行上下文

当应用 eval 函数的时候,eval 代码也会被编译,并创立执行上下文。

10.2 蕴含内容

执行上下文在不同的版本中定义不同,《重学前端》中对此进行了总结,目前次要有三个版本:

  1. 执行上下文在 ES3 中,蕴含三个局部。
  • scope:作用域,也经常被叫做作用域链。
  • variable object:变量对象,用于存储变量的对象。
  • this value:this 值。
  1. 在 ES5 中,咱们改良了命名形式,把执行上下文最后的三个局部改为上面这个样子。
  • lexical environment:词法环境,当获取变量时应用。(通过 let、const、with()、try-catch 创立的变量存在词法环境中)
  • variable environment:变量环境,当申明变量时应用。(通过 var 申明或 function(){}申明的变量存在变量环境中)
  • this value:this 值。
  1. 在 ES2018 中,执行上下文又变成了这个样子,this 值被纳入 lexical environment,然而减少了不少内容。
  • lexical environment:词法环境,当获取变量或者 this 值时应用。
  • variable environment:变量环境,当申明变量时应用
  • code evaluation state:用于复原代码执行地位。
  • Function:执行的工作是函数时应用,示意正在被执行的函数。
  • ScriptOrModule:执行的工作是脚本或者模块时应用,示意正在被执行的代码。
  • Realm:应用的根底库和内置对象实例。
  • Generator:仅生成器上下文有这个属性,示意以后生成器。

10.3 执行上下文生命周期

在执行上下文生命周期局部(将依照 ES3 阶段的内容进行介绍,因为自我感觉后续定义的名词内容尽管更全面,但背起来的确不是很容易),分为创立阶段和执行阶段两个阶段,每个阶段负责不同的事件。(注:,每一部分都是一个问题,具体解释看后续百题斩。)

  1. 创立阶段

创立阶段次要负责生成变量对象、建设作用域链以及确定 this 指向。

  1. 代码执行阶段

创立实现之后,就会开始执行代码,这个时候,会实现变量赋值,函数援用,以及执行其余代码。

10.4 代码执行过程

百题斩【008-009】介绍了代码和函数的执行过程,然而这个介绍只是从宏观方面进行介绍,并没有进行具体的介绍,上面将从调用栈这个角度具体论述一下代码的执行过程。

  1. 创立 全局上下文 (global EC)。将其压入栈底;
  2. 全局执行上下文 (caller) 逐行 自上而下 执行。遇到函数时, 函数执行上下文 (callee) 被 push 到执行栈顶层;
  3. 函数执行上下文被激活,成为 active EC, 开始执行函数中的代码,caller 被挂起;
  4. 函数执行完后,callee 被 pop 移除出执行栈,控制权交还全局上下文 (caller),继续执行;

上面将举一个例子来论述该执行过程。

var a = 1;
function f1() {// ……}

function f2() {f1();
    // ……
}

f2();

上述代码的调用栈如下所示:

  1. 首先创立全局执行上下文,并将全局执行上下文压入栈底;其中变量 a、函数 f1 和 f2 都将被保留在全局执行上下文的变量环境中;
  2. 全局执行上下文开始执行,变量 a 被赋值为 1,当调用函数 f2 是,会创立对应的函数执行上下文并压入调用栈,在函数 f2 的执行上下文被创立好后,将进入代码执行阶段;
  3. 函数 f2 执行过程中会调用函数 f1,创立对应的函数执行上下文并压入调用栈;f1 进行执行阶段;
  4. f1 函数返回时,该函数的执行上下文从栈顶弹出;
  5. 紧接着 f2 函数返回,f2 函数对应的执行上下文也从栈顶弹出;
  6. 至此代码执行敞开,当结束页面的时候全局执行上下文销毁。

10.5 论断

理解了执行上下文,须要记住一些结论性的货色

  1. 在调用栈中只有栈顶的上下文处于执行中,其余上下文须要期待;
  2. 全局上下文只有惟一的一个,它在浏览器敞开时出栈;
  3. 函数的执行上下文的个数没有限度;
  4. 每次某个函数被调用,就会有个新的执行上下文为其创立,并把该执行上下文压入调用栈,而后 JavaScript 引擎开销执行函数代码,即便是调用的本身函数,也是如此;
  5. 以后函数执行结束后,JavaScript 引擎会将该函数的执行上下文弹出栈;
  6. 当调配的调用栈空间被占满时,会引发“堆栈溢出”问题。

看一看

1. 如果感觉这篇文章还不错,来个分享、点赞吧,让更多的人也看到

2. 关注公众号执鸢者,与号主一起斩杀前端百题。

正文完
 0