} } FunctionExectionContext = { LexicalEnvironment: { EnvironmentRecord: { Type: "Declarative", // 标识符绑定在这里 } outer: } } ``` #### **变量环境:** 它也是一个词法环境,其 `EnvironmentRecord` 包含了由 **VariableStatements** 在此执行上下文创建的绑定。 如上所述,变量环境也是一个词法环境,因此它具有上面定义的词法环境的所有属性。 在 ES6 中,**LexicalEnvironment** 组件和 **VariableEnvironment** 组件的区别在于前者用于存储函数声明和变量( `let` 和 `const` )绑定,而后者仅用于存储变量( `var` )绑定。 让我们结合一些代码示例来理解上述概念: ```javascript let a = 20; const b = 30; var c; function multiply(e, f) { var g = 20; return e * f * g; } c = multiply(20, 30); ``` 执行上下文如下所示: ```javascript GlobalExectionContext = { ThisBinding: , LexicalEnvironment: { EnvironmentRecord: { Type: "Object", // 标识符绑定在这里 a: < uninitialized >, b: < uninitialized >, multiply: < func > } outer: }, VariableEnvironment: { EnvironmentRecord: { Type: "Object", // 标识符绑定在这里 c: undefined, } outer: } } FunctionExectionContext = { ThisBinding: , LexicalEnvironment: { EnvironmentRecord: { Type: "Declarative", // 标识符绑定在这里 Arguments: {0: 20, 1: 30, length: 2}, }, outer: }, VariableEnvironment: { EnvironmentRecord: { Type: "Declarative", // 标识符绑定在这里 g: undefined }, outer: } } ``` **注意** — 只有在遇到函数 `multiply` 的调用时才会创建函数执行上下文。 你可能已经注意到了 `let` 和 `const` 定义的变量没有任何与之关联的值,但 `var` 定义的变量被设置为 `undefined`。 这是因为在创建阶段,代码会被扫描并解析变量和函数声明,其中函数声明存储在环境中,而变量会被设置为 `undefined`(在 `var` 的情况下)或保持未初始化(在 `let` 和 `const` 的情况下)。 这就是为什么你可以在声明之前访问 `var` 定义的变量(尽管是 `undefined` ),但如果在声明之前访问 `let` 和 `const` 定义的变量就会提示引用错误。 这就是我们所谓的变量提升。 ### 执行阶段 这是整篇文章中最简单的部分。在此阶段,完成对所有变量的分配,最后执行代码。 **注意** — 在执行阶段,如果 JavaScript 引擎在源代码中声明的实际位置找不到 `let` 变量的值,那么将为其分配 `undefined` 值。 ## 结论 我们已经讨论过 JavaScript 程序内部是如何执行的。虽然要成为一名卓越的 JavaScript 开发人员并不需要学会所有这些概念,但是如果对上面概念能有不错的理解将有助于你更轻松,更深入地理解其他概念,如变量提升,域和闭包等。 > 如果发现译文存在错误或其他需要改进的地方,欢迎到 [掘金翻译计划](https://github.com/xitu/gold-miner) 对译文进行修改并 PR,也可获得相应奖励积分。文章开头的 **本文永久链接** 即为本文在 GitHub 上的 MarkDown 链接。 --- > [掘金翻译计划](https://github.com/xitu/gold-miner) 是一个翻译优质互联网技术文章的社区,文章来源为 [掘金](https://juejin.im) 上的英文分享文章。内容覆盖 [Android](https://github.com/xitu/gold-miner#android)、[iOS](https://github.com/xitu/gold-miner#ios)、[前端](https://github.com/xitu/gold-miner#前端)、[后端](https://github.com/xitu/gold-miner#后端)、[区块链](https://github.com/xitu/gold-miner#区块链)、[产品](https://github.com/xitu/gold-miner#产品)、[设计](https://github.com/xitu/gold-miner#设计)、[人工智能](https://github.com/xitu/gold-miner#人工智能)等领域,想要查看更多优质译文请持续关注 [掘金翻译计划](https://github.com/xitu/gold-miner)、[官方微博](http://weibo.com/juejinfanyi)、[知乎专栏](https://zhuanlan.zhihu.com/juejinfanyi)。 " />
触不到的你游戏手机版2026下载
- 类型:生活服务
- 大小:59.97MB
- 语言:简体中文
- 厂商:触不到的你游戏手机版2026下载
- 更新:2026-06-01 17:20:22
举报
详情介绍
# [译] 理解 JavaScript 中的执行上下文和执行栈  ## 目录 * [什么是执行上下文](#什么是执行上下文) * [执行上下文的类型](#执行上下文的类型) * [执行栈](#执行栈) * [怎样创建执行上下文?](#怎样创建执行上下文) * [结论](#结论) ## 什么是执行上下文 简而言之,执行上下文就是当前 JavaScript 代码被解析和执行时所在环境的抽象概念, JavaScript 中运行任何的代码都是在执行上下文中运行。 ## 执行上下文的类型 执行上下文总共有三种类型: * **全局执行上下文**: 这是默认的、最基础的执行上下文。不在任何函数中的代码都位于全局执行上下文中。它做了两件事:1. 创建一个全局对象,在浏览器中这个全局对象就是 window 对象;2. 将 `this` 指针指向这个全局对象。一个程序中只能存在一个全局执行上下文。 * **函数执行上下文**: 每次调用函数时,都会为该函数创建一个新的执行上下文。每个函数都拥有自己的执行上下文,但是只有在函数被调用的时候才会被创建。一个程序中可以存在任意数量的函数执行上下文。每当一个新的执行上下文被创建,它都会按照特定的顺序执行一系列步骤,具体过程将在本文后面讨论。 * **Eval 函数执行上下文**: 运行在 `eval` 函数中的代码也获得了自己的执行上下文,但由于 Javascript 开发人员不常用 eval 函数,所以在这里不再讨论。 ## 执行栈 执行栈,在其他编程语言中也被叫做“调用栈”,是一种拥有 LIFO(后进先出)数据结构的栈,被用来存储代码运行时创建的所有执行上下文。 当 JavaScript 引擎第一次遇到你的脚本时,它会创建一个全局的执行上下文并且压入当前执行栈。每当引擎遇到一个函数调用,它会为该函数创建一个新的执行上下文并压入栈的顶部。 引擎会执行那些执行上下文位于栈顶的函数。当该函数执行结束时,执行上下文从栈中弹出,控制流程到达当前栈中的下一个上下文。 让我们通过下面的代码示例来理解: ```javascript let a = 'Hello World!'; function first() { console.log('Inside first function'); second(); console.log('Again inside first function'); } function second() { console.log('Inside second function'); } first(); console.log('Inside Global Execution Context'); ```  上述代码的执行上下文栈。 当上述代码在浏览器加载时,JavaScript 引擎创建了一个全局执行上下文并把它压入当前执行栈。当遇到 `first()` 函数调用时,JavaScript 引擎为该函数创建一个新的执行上下文并把它压入当前执行栈的顶部。 当从 `first()` 函数内部调用 `second()` 函数时,JavaScript 引擎为 `second()` 函数创建了一个新的执行上下文并把它压入当前执行栈的顶部。当 `second()` 函数执行完毕,它的执行上下文会从当前栈弹出,并且控制流程到达下一个执行上下文,即 `first()` 函数的执行上下文。 当 `first()` 执行完毕,它的执行上下文从栈弹出,控制流程到达全局执行上下文。一旦所有代码执行完毕,JavaScript 引擎从当前栈中移除全局执行上下文。 ## 怎样创建执行上下文? 到现在,我们已经看过 JavaScript 怎样管理执行上下文了,现在让我们了解 JavaScript 引擎是怎样创建执行上下文的。 执行上下文分两个阶段创建:**1)创建阶段;** **2)执行阶段**。 ### 创建阶段 在任意的 JavaScript 代码被执行前,执行上下文处于创建阶段。在创建阶段中总共发生了三件事情: 1. 确定 **this** 的值,也被称为 **This Binding**。 2. **LexicalEnvironment(词法环境)** 组件被创建。 3. **VariableEnvironment(变量环境)** 组件被创建。 因此,执行上下文可以在概念上表示如下: ```javascript ExecutionContext = { ThisBinding = , LexicalEnvironment = { ... }, VariableEnvironment = { ... }, } ``` #### **This Binding:** * 在全局执行上下文中,`this` 的值指向全局对象,在浏览器中,`this` 的值指向 window 对象。 * 在函数执行上下文中,`this` 的值取决于函数的调用方式。如果它被一个对象引用调用,那么 `this` 的值被设置为该对象,否则 `this` 的值被设置为全局对象或 `undefined`(严格模式下)。例如: ```javascript let person = { name: 'peter', birthYear: 1994, calcAge: function() { console.log(2018 - this.birthYear); } } person.calcAge(); // 'this' 指向 'person', 因为 'calcAge' 是被 'person' 对象引用调用的。 let calculateAge = person.calcAge; calculateAge(); // 'this' 指向全局 window 对象,因为没有给出任何对象引用 ``` #### **词法环境(Lexical Environment)** [官方 ES6](http://ecma-international.org/ecma-262/6.0/) 文档将词法环境定义为: > 词法环境是一种规范类型,基于 ECMAScript 代码的词法嵌套结构来定义标识符与特定变量和函数的关联关系。词法环境由环境记录(environment record)和可能为空引用(null)的外部词法环境组成。 简而言之,词法环境是一个包含**标识符变量映射**的结构。(这里的**标识符**表示变量/函数的名称,**变量**是对实际对象【包括函数类型对象】或原始值的引用)。 在词法环境中,有两个组成部分:(1)**环境记录(environment record)** (2)**对外部环境的引用**。 1. **环境记录**是存储变量和函数声明的实际位置。 2. **对外部环境的引用**意味着它可以访问其外部词法环境。 词法环境有两种类型: * **全局环境**(在全局执行上下文中)是一个没有外部环境的词法环境。全局环境的外部环境引用为 **null**。它拥有一个全局对象(window 对象)及其关联的方法和属性(例如数组方法)以及任何用户自定义的全局变量,`this` 的值指向这个全局对象。 * **函数环境**,用户在函数中定义的变量被存储在**环境记录**中。对外部环境的引用可以是全局环境,也可以是包含内部函数的外部函数环境。 **注意** — 对于**函数环境**而言,**环境记录** 还包含了一个 `arguments` 对象,该对象包含了索引和传递给函数的参数之间的映射以及传递给函数的参数的**长度(数量)**。例如,下面函数的 `arguments` 对象如下所示: ```javascript function foo(a, b) { var c = a + b; } foo(2, 3); // arguments 对象 Arguments: {0: 2, 1: 3, length: 2} ``` **环境记录** 同样有两种类型(如下所示): * **声明性环境记录** 存储变量、函数和参数。一个函数环境包含声明性环境记录。 * **对象环境记录** 用于定义在全局执行上下文中出现的变量和函数的关联。全局环境包含对象环境记录。 抽象地说,词法环境在伪代码中看起来像这样: ```javascript GlobalExectionContext = { LexicalEnvironment: { EnvironmentRecord: { Type: "Object", // 标识符绑定在这里 } outer: } } FunctionExectionContext = { LexicalEnvironment: { EnvironmentRecord: { Type: "Declarative", // 标识符绑定在这里 } outer: } } ``` #### **变量环境:** 它也是一个词法环境,其 `EnvironmentRecord` 包含了由 **VariableStatements** 在此执行上下文创建的绑定。 如上所述,变量环境也是一个词法环境,因此它具有上面定义的词法环境的所有属性。 在 ES6 中,**LexicalEnvironment** 组件和 **VariableEnvironment** 组件的区别在于前者用于存储函数声明和变量( `let` 和 `const` )绑定,而后者仅用于存储变量( `var` )绑定。 让我们结合一些代码示例来理解上述概念: ```javascript let a = 20; const b = 30; var c; function multiply(e, f) { var g = 20; return e * f * g; } c = multiply(20, 30); ``` 执行上下文如下所示: ```javascript GlobalExectionContext = { ThisBinding: , LexicalEnvironment: { EnvironmentRecord: { Type: "Object", // 标识符绑定在这里 a: < uninitialized >, b: < uninitialized >, multiply: < func > } outer: }, VariableEnvironment: { EnvironmentRecord: { Type: "Object", // 标识符绑定在这里 c: undefined, } outer: } } FunctionExectionContext = { ThisBinding: , LexicalEnvironment: { EnvironmentRecord: { Type: "Declarative", // 标识符绑定在这里 Arguments: {0: 20, 1: 30, length: 2}, }, outer: }, VariableEnvironment: { EnvironmentRecord: { Type: "Declarative", // 标识符绑定在这里 g: undefined }, outer: } } ``` **注意** — 只有在遇到函数 `multiply` 的调用时才会创建函数执行上下文。 你可能已经注意到了 `let` 和 `const` 定义的变量没有任何与之关联的值,但 `var` 定义的变量被设置为 `undefined`。 这是因为在创建阶段,代码会被扫描并解析变量和函数声明,其中函数声明存储在环境中,而变量会被设置为 `undefined`(在 `var` 的情况下)或保持未初始化(在 `let` 和 `const` 的情况下)。 这就是为什么你可以在声明之前访问 `var` 定义的变量(尽管是 `undefined` ),但如果在声明之前访问 `let` 和 `const` 定义的变量就会提示引用错误。 这就是我们所谓的变量提升。 ### 执行阶段 这是整篇文章中最简单的部分。在此阶段,完成对所有变量的分配,最后执行代码。 **注意** — 在执行阶段,如果 JavaScript 引擎在源代码中声明的实际位置找不到 `let` 变量的值,那么将为其分配 `undefined` 值。 ## 结论 我们已经讨论过 JavaScript 程序内部是如何执行的。虽然要成为一名卓越的 JavaScript 开发人员并不需要学会所有这些概念,但是如果对上面概念能有不错的理解将有助于你更轻松,更深入地理解其他概念,如变量提升,域和闭包等。 > 如果发现译文存在错误或其他需要改进的地方,欢迎到 [掘金翻译计划](https://github.com/xitu/gold-miner) 对译文进行修改并 PR,也可获得相应奖励积分。文章开头的 **本文永久链接** 即为本文在 GitHub 上的 MarkDown 链接。 --- > [掘金翻译计划](https://github.com/xitu/gold-miner) 是一个翻译优质互联网技术文章的社区,文章来源为 [掘金](https://juejin.im) 上的英文分享文章。内容覆盖 [Android](https://github.com/xitu/gold-miner#android)、[iOS](https://github.com/xitu/gold-miner#ios)、[前端](https://github.com/xitu/gold-miner#前端)、[后端](https://github.com/xitu/gold-miner#后端)、[区块链](https://github.com/xitu/gold-miner#区块链)、[产品](https://github.com/xitu/gold-miner#产品)、[设计](https://github.com/xitu/gold-miner#设计)、[人工智能](https://github.com/xitu/gold-miner#人工智能)等领域,想要查看更多优质译文请持续关注 [掘金翻译计划](https://github.com/xitu/gold-miner)、[官方微博](http://weibo.com/juejinfanyi)、[知乎专栏](https://zhuanlan.zhihu.com/juejinfanyi)。
游戏信息
- 游戏大小59.97MB
- 当前版本5.8.18
- 系统要求需要支持安卓系统5.2以上
- 是否收费免费
- 游戏语言中文
- 发行商触不到的你游戏手机版2026下载
- 包名com.r7dix.qva30
- MD57o2gpaml1ecj4h6nfi9twqrz30s58xuk
游戏截图
string(37) "/image/20260601/tzumyh_1780305539.jpg"
-