理解JavaScript中的执行上下文和执行栈

上传人:cl****1 文档编号:457704566 上传时间:2022-11-11 格式:DOCX 页数:6 大小:22.41KB
返回 下载 相关 举报
理解JavaScript中的执行上下文和执行栈_第1页
第1页 / 共6页
理解JavaScript中的执行上下文和执行栈_第2页
第2页 / 共6页
理解JavaScript中的执行上下文和执行栈_第3页
第3页 / 共6页
理解JavaScript中的执行上下文和执行栈_第4页
第4页 / 共6页
理解JavaScript中的执行上下文和执行栈_第5页
第5页 / 共6页
点击查看更多>>
资源描述

《理解JavaScript中的执行上下文和执行栈》由会员分享,可在线阅读,更多相关《理解JavaScript中的执行上下文和执行栈(6页珍藏版)》请在金锄头文库上搜索。

1、什么执行上下文?简而言之,执行上下文评估和执行JavaScript 代码的环境的抽象概念。每当 Javascript 代码在运行的时候,它都在执行上下文中运行。执行上下文的类型JavaScript 中有三种执行上下文类型。全局执行上下文 这默认或者说基础的上下文,任何不在函数内部的代码都在全局上下文中。它会执行两件事:创建一个全局的 window 对象 (浏览器的情况下) ,并且设置 this 的值等于这个全局对象。一个程序中只会有一个全局执行上下文。函数执行上下文 每当一个函数被调用时,都会为该函数创建一个新的上下文。每个函数都有它自己的执行上下文,不过在函数被调用时创建的。函数上下文可以有

2、任意多个。每当一个新的执行上下文被创建,它会按定义的顺序 (将在后文讨论)执行一系列步骤。Eval 函数执行上下文 执行在 eval 函数内部的代码也会有它属于自己的执行上下文,但由于JavaScript发者并不经常使用eval,所以在这里不会讨论它。执行栈执行栈,也就在其它编程语言中所说的调用栈,一种拥有LIFO(后进先出)数据结构的栈,被用来存储代码运行时创建的所有执行上下文。当 JavaScript 引擎次遇到你的脚本时,它会创建一个全局的执行上下文并且压入当前执行栈。每当引擎遇到一个函数调用,它会为该函数创建一个新的执行上下文并压入栈的顶部。引擎会执行那些执行上下文位于栈顶的函数。当该

3、函数执行结束时,执行上下文从栈中弹出,控制流程到达当前栈中的下一个上下文。让们通过的代码示例来理解:leta=HelloWorld!;functionfirst()console.log(Insidefirstfunction);second();console.log(Againinsidefirstfunction);functionsecond()console.log(Insidesecondfunction);first();console.log(InsideGlobalExecutionContext);当上述代码在浏览器加载时, JavaScript 引擎创建了一个全局执行上下

4、文并把它压入当前执行栈。当遇到 first() 函数调用时, JavaScript 引擎为该函数创建一个新的执行上下文并把它压入当前执行栈的顶部。当从first()函数内部调用second()函数时,JavaScript引擎为second()函数创建了一个新的执行上下文并把它压入当前执行栈的顶部。当 second() 函数执行完毕,它的执行上下文会从当前栈弹出,并且控制流程到达下一个执行上下文,即first() 函数的执行上下文。当 first() 执行完毕,它的执行上下文从栈弹出,控制流程到达全局执行上下文。一旦所有代码执行完毕, JavaScript 引擎从当前栈中移除全局执行上下文。怎么

5、创建执行上下文?到现在,们已经看过JavaScript 怎样管理执行上下文了,现在让们了解JavaScript 引擎怎样创建执行上下文的。创建执行上下文有两个阶段:1)创建阶段和2) 执行阶段。TheCreationPhase 在 JavaScript 代码执行前,执行上下文将经历创建阶段。在创建阶段会发生三件事:this 值的决定,即们所熟知的 This 绑定。创建词法环境组件。创建变量环境组件。所以执行上下文在概念上表示如下:ExecutionContext=ThisBinding=,LexicalEnvironment=.,VariableEnvironment=.,This 绑定:在全

6、局执行上下文中, this 的值指向全局对象。 (在浏览器中,this 引用 Window 对象 ) 。在函数执行上下文中,this 的值取决于该函数如何被调用的。如果它被一个引用对象调用,那么 this 会被设置成那个对象,否则 this 的值被设置为全局对象或者 undefined( 在严格模式下) 。例如:letfoo= baz:function() console.log(this);foo.baz();/this引用foo,因为baz被/ 对象 foo 调用letbar=foo.baz;bar();/this 指向全局 window 对象,因为/ 没有指定引用对象词法环境的ES6文档

7、把词法环境定义为词法环境一种规范类型,基于 ECMAScript 代码的词法嵌套结构来定义标识符和具体变量和函数的关联。一个词法环境由环境记录器和一个可能的引用外部词法环境的空值组成。简单来说词法环境一种持有标识符 变量映的结构。 (这里的标识符指的变量/函数的名字,而变量对实际对象包含函数类型对象 或原始数据的引用 ) 。现在,在词法环境的内部有两个组件: (1)环境记录器和 (2) 一个外部环境的引 用。环境记录器存储变量和函数声明的实际位置。外部环境的引用意味着它可以访问其父级词法环境(作用域) 。词法环境有两种类型:全局环境 (在全局执行上下文中 ) 没有外部环境引用的词法环境。全局环

8、境的外部环境引用 null 。它拥有内建的 Object/Array/ 等、在环境记录器内的原型函数(关联全局对象,比如 window 对象) 还有任何用户定义的全局变量,并且this 的值指向全局对象。在函数环境中,函数内部用户定义的变量存储在环境记录器中。并且引用的外部环境可能全局环境,或者任何包含此内部函数的外部函数。环境记录器也有两种类型(如上 !) :声明式环境记录器存储变量、函数和参数。对象环境记录器用来定义出现在全局上下文中的变量和函数的关系。简而言之,在全局环境中,环境记录器对象环境记录器。在函数环境中,环境记录器声明式环境记录器。注意 对于函数环境,声明式环境记录器还包含了一

9、个传递给函数的arguments 对象 (此对象存储索引和参数的映)和传递给函数的参数的length 。抽象地讲,词法环境在伪代码中看起来像这样:GlobalExectionContext=LexicalEnvironment:EnvironmentRecord:Type:Object,/ 在这里绑定标识符outer:FunctionExectionContext=LexicalEnvironment:EnvironmentRecord:Type:Declarative,/ 在这里绑定标识符outer:变量环境:它同样一个词法环境,其环境记录器持有变量声明语句在执行上下文中创建的绑定关系。如上

10、所述,变量环境也一个词法环境,所以它有着上面定义的词法环境的所有属性。在 ES6 中,词法环境组件和变量环境的一个不同就前者被用来存储函数声明和变量 (let 和 const) 绑定,而后者只用来存储var 变量绑定。们看样例代码来理解上面的概念:leta=20;constb=30;varc;functionmultiply(e,f) varg=20;returne*f*g;c=multiply(20,30);执行上下文看起来像这样:GlobalExectionContext= ThisBinding:, LexicalEnvironment: EnvironmentRecord: Type:

11、Object,/ 在这里绑定标识符a:, b:, multiply: outer:,VariableEnvironment: EnvironmentRecord: Type:Object, / 在这里绑定标识符 c:undefined,outer:FunctionExectionContext=ThisBinding:,LexicalEnvironment:EnvironmentRecord:Type:Declarative,/ 在这里绑定标识符Arguments:0:20,1:30,length:2,outer:,VariableEnvironment:EnvironmentRecord:T

12、ype:Declarative,/ 在这里绑定标识符g:undefined,outer:注意 只有遇到调用函数multiply 时,函数执行上下文才会被创建。可能你已经注意到 let 和 const 定义的变量并没有关联任何值,但var 定义的变量被设成了 undefined 。这因为在创建阶段时,引擎检查代码找出变量和函数声明,虽然函数声明完全存储在环境中,但变量最初设置为 undefined(var 情况下 ) ,或者未初始化 (let 和const 情况下)。这就为什么你可以在声明之前访问 var 定义的变量(虽然 undefined) ,但在声明之前访问let 和 const 的变量会得到一个引用。这就们说的变量声明提升。执行阶段这整篇文章中最简单的部分。在此阶段,完成对所有这些变量的分配,最后执行代码。注意 在执行阶段,如果JavaScript 引擎不能在源码中声明的实际位置找到let 变量的值,它会被赋值为 undefined 。结论们已经讨论过JavaScript 程序内部如何执行的。虽然要成为一名卓越的JavaScript 发者并不需要学会全部这些概念,但如果对上面概念能有不错的理解将有助于你更轻松,更深入地理解其他概念,如变量声明提升,作用域和闭包。就这样,如果你发现这篇文章有用,请击

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 商业/管理/HR > 营销创新

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号