执行上下文

执行上下文

执行上下文也叫执行环境?为什么呢就让我这个英语zz来解释下

context:环境; 上下文

执行上下文

执行环境中定义了变量或函数有权访问的其他数据,决定了他们给各自行为,每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保持在这个对象中,虽然我们无法访问到这个对象,但是解析器可以在处理数据的时候在后台使用他 

 执行上下文类型:

  • 全局执行上下文 :只有一个,浏览器中的全局对象就是 window 对象,this 指向这个全局对象。
  • 函数执行上下文 : 每当一个函数被调用时, 都会为该函数创建一个新的上下文。每个函数都有它自己的执行上下文,不过是在函数被调用时创建的。函数上下文可以有任意多个。每当一个新的执行上下文被创建,它会按定义的顺序,在执行栈中(将在后文讨论)执行一系列步骤。
  • Eval 函数执行上下文 — 执行在 eval 函数内部的代码也会有它属于自己的执行上下文

 执行栈

执行栈,也就是在其它编程语言中所说的“调用栈”,是一种拥有 LIFO(后进先出)数据结构的栈,被用来存储代码运行时创建的所有执行上下文

后进先出:也就是只有一个出口(数组开头的位置),后进的执行上下文也是离空最近的,所以就先出

当 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');

1:只有全局执行上下文

2:first()函数执行,执行栈中添加first()函数的执行上下文

3:在first函数执行的过程中Second函数执行了,second函数的执行上下文加入到执行栈中

4:Second函数执行完毕,移除执行栈

5:Frist()函数执行完毕移除执行栈

怎么创建执行上下文?

在 JavaScript 代码执行前,执行上下文将经历创建阶段。在创建阶段会发生三件事:

  1. this 值的决定,即我们所熟知的 This 绑定
  2. 创建词法环境组件。
  3. 创建变量环境组件。
ExecutionContext = {
  ThisBinding = <this value>,
  LexicalEnvironment = { ... },
  VariableEnvironment = { ... },
}

This 绑定:

在全局执行上下文中,this 的值指向全局对象。(在浏览器中,this引用 Window 对象)。

在函数执行上下文中,this 的值取决于该函数是如何被调用的。如果它被一个引用对象调用,那么 this 会被设置成那个对象,否则 this 的值被设置为全局对象或者 undefined(在严格模式下)

词法环境

词法环境变量环境内部有两个组件:(1) 环境记录器和 (2) 一个外部环境的引用(可能存在)

 A Lexical Environment consists of an Environment Record and a possibly null reference to an outer Lexical Environment.

词法环境由一个环境记录和一个可能为空的外部词法环境引用组成

(1) 环境记录器:获取变量和函数声明的实际位置

(2) 一个外部环境的引用:和它可以访问其父级词法环境

但是有2种词法环境变量环境类型一个是全局的一个是函数的分2中不同的情况

记录器包含的东西

Each declarative Environment Record is associated with an ECMAScript program scope containing variable, constant, let, class, module, import, and/or function declarations. A declarative Environment Record binds the set of identifiers defined by the declarations contained within its scope.

每个声明性环境记录都与包含变量、常量、let、类、模块、导入和/或函数声明的ECMAScript程序范围相关联。声明性环境记录绑定由其范围内包含的声明所定义的一组标识符。

注意 :不用的情况环境中的环境记录器参数的值是不同的

当声明对象的时候;函数的时候;变量的时候,例如函数就有保护了专属的字段(this来判断函数执行的环境,newTarget判断构造函数),一些公用的比如WithBaseObject()(判断是否使用with环境),[[scope]]:作用域

执行上下文和作用域的区别?

由这个[[scope]]字段可以得出作用域其实就是执行上下文中的词法环境内标记的一个字段

下面我对规范的翻译

词法环境是一种规范类型,用于根据ECMAScript代码的词法嵌套结构定义标识符与特定变量和函数的关联。词法环境由一个环境记录和一个可能为空的外部词法环境引用组成。通常,词法环境与ECMAScript代码的某些特定语法结构相关联,比如函数声明、BlockStatement或TryStatement的Catch子句,每次计算这些代码时都会创建一个新的词法环境。

环境记录记录在其关联的词法环境范围内创建的标识符绑定。它被称为词汇环境的环境记录。

外部环境引用用于对词法环境值的逻辑嵌套进行建模。(内部)词汇环境的外部引用是对逻辑上围绕着内部词汇环境的词汇环境的引用。外部词汇环境当然也有它自己的外部词汇环境。词汇环境可以作为多个内部词汇环境的外部环境。例如,如果一个函数声明包含两个嵌套函数声明,那么每个嵌套函数的词法环境都将有周围函数当前求值的词法环境作为它们的外部词法环境。

全局环境是没有外部环境的词汇环境。全局环境的外部环境引用为空。一个全局环境的EnvironmentRecord可以用标识符绑定预填充,并包含一个相关的全局对象,该对象的属性提供了一些全局环境的标识符绑定。在执行ECMAScript代码时,可能会向全局对象添加其他属性,初始属性也可能被修改。

模块环境是一个词法环境,它包含模块顶级声明的绑定。它还包含由模块显式导入的绑定。模块环境的外部环境是全局环境。

函数环境是对应于调用ECMAScript函数对象的词法环境。函数环境可以建立一个新的this绑定。函数环境还捕获支持超方法调用所需的状态。

词法环境和环境记录值纯粹是规范机制,不需要对应于ECMAScript实现的任何特定工件。ECMAScript程序不可能直接访问或操作这些值。

变量环境

基本和词法环境一样,但是变量环境是在声明的时候使用

The LexicalEnvironment and VariableEnvironment components of an execution context are always Lexical Environments.

很关键的一句话就是说Lexical Environments(词汇环境).=== 词法环境 + 变量环境

资源

ECMA-262 - Ecma International (8.3)

ES5中

LexicalEnvironmentIdentifies the Lexical Environment used to resolve identifier references made by code within this execution context. (zqx:获取是使用)
VariableEnvironmentIdentifies the Lexical Environment whose environment record holds bindings created by VariableStatements and FunctionDeclarations within this execution context. (zqx:声明时候使用)
ThisBindingThe value associated with the this keyword within ECMAScript code associated with this execution context.

The LexicalEnvironment and VariableEnvironment components of an execution context are always Lexical Environments. When an execution context is created its LexicalEnvironment and VariableEnvironment components initially have the same value. The value of the VariableEnvironment component never changes while the value of the LexicalEnvironment component may change during execution of code within an execution context. 

执行上下文的LexicalEnvironment和VariableEnvironment组件总是词法环境。当创建执行上下文时,它的LexicalEnvironment和VariableEnvironment组件最初具有相同的值。VariableEnvironment组件的值永远不会改变,而LexicalEnvironment组件的值可能会在执行上下文中的代码执行过程中改变。

​​​​​​

ES6中

在 ES6 中,词法环境组件和变量环境的一个不同就是前者被用来存储函数声明和变量(let 和 const)绑定,而后者只用来存储 var 变量绑定。

ECMA-262 - Ecma International (在8.3那个位置)

  • lexical environment:词法环境,当获取变量或者 this 值时使用。  //ES6将this也并入了词法环境
  • variable environment:变量环境,当声明变量时使用。
  • code evaluation state:用于恢复代码执行位置。
  • Function:执行的任务是函数时使用,表示正在被执行的函数。
  • ScriptOrModule:执行的任务是脚本或者模块时使用,表示正在被执行的代码。(async 的时候有可能用到)
  • Realm:使用的基础库和内置对象实例。(当用Number,string这个基本类型写方法隐式转换的时候,和var obj = {}的时候由于这些对象都是由原型的,如果我们没有Realm,就不知道他们的原型)
  • Generator:仅生成器上下文有这个属性,表示当前生成器。(可能存在)

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值