JavaScript执行环境/执行上下文(Execution Content)

关键词:
执行上下文、词法环境、变量环境、this、执行上下文栈、变量对象、做用域链javascript

Execution Content 执行上下文

执行上下文定义了变量或函数有权访问的其余数据,决定了他们各自的行为。当javascript代码执行一段可执行代码时,会建立对应的执行上下文; 代码所有执行完后,该执行上下文也会被销毁,保存在其中的变量和函数定义也随之被销毁。执行上下文会管理代码执行过程当中使用的内存。前端

执行上下文分3种:java

  • Global-Execution-Content 全局执行上下文
    在web浏览器中,全局执行上下文就是window对象
  • Function-Execution-Content 函数执行上下文
    每次调用函数时,都会建立一个函数执行上下文
  • eval执行上下文

建立执行上下文

javascript引擎建立执行上下文有两个阶段:web

  1. 建立阶段
    1. this绑定
    2. 建立词法环境 Lexical-Environment
    3. 建立变量环境 Variable-Environment
  2. 执行阶段

this绑定

在全局执行上下文中,this指向全局对象(浏览器中指window对象);
在函数执行上下文中,this的值取决于函数是如何并调用的。若是函数被一个引用对象调用,那么this会被设置成这个对象,不然this会被设置为window或undefined(严格模式下)浏览器

var obj = {
    getThis: function(){
        return this
    }
}

obj.getThis();  // obj

var fn = obj.getThis
fn();     // window

复制代码

词法环境 Lexical-Environment

词法环境是一种规范类型,基于ECMAScript代码的词法嵌套结构来定义“标识符”和具体函数和变量的关系。存储let,const 定义的函数声明和变量绑定bash

一个词法环境由一个环境记录器和一个(可能存在的)对外部词法环境的引用组成。函数

  1. 环境记录器
    环境记录器存储变量和函数声明的具体位置。
    函数执行环境中环境记录器为声明式环境记录器,存储变量、函数、和函数参数,声明式环境记录器包含一个传递给函数的argument对象;
    全局执行环境中的环境记录器为对象环境记录器,定义出如今全局执行上下文中的变量和函数的关系。
  2. 对外部词法环境的引用
    经过这个引用能够访问父级词法环境

变量环境 Variable-Environment

变量环境其实也是一个词法环境,用来存储变量声明语句在执行上下文中建立的绑定关系,即,存储var声明的变量的绑定ui

在建立阶段,let、const定义的变量变量没有关联任何值,可是var声明的变量会被设置为undefined,因此var变量在声明以前访问值为undefined,但不会报错,即变量声明提高。let、const变量声明前访问会致使引用错误。this

执行阶段

执行阶段完成对全部变量的分配,并执行代码。spa

Execution Content Stack 执行上下文栈ECS

javascript引擎建立执行上下文栈管理执行代码是建立的全部执行上下文。

当JavaScript脚本第一次执行代码时,会建立一个全局执行上下文,并压入执行栈;以后每次调用函数时,会为该函数建立一个函数执行上下文并压入栈,当函数执行结束,对应当执行上下文从栈中弹出。

下面两段代码的执行结果同样"local",可是执行上下文栈的变化不一样。

var scope = "global";
function checkScope(){
    var scope = "local";
    function fn(){
        return scope;
    }
    return fn();
}
checkScope();

// 方法执行时 执行上下文栈的变化以下
ESCStack.push(<checkScope> function-Context)
ESCStack.push(<fn> function-Context)
ESCStack.pop()
ESCStack.pop()
复制代码
var scope = "global";
function checkScope(){
    var scope = "local";
    function fn(){
        return scope;
    }
    return fn;
}
checkScope()();

// 方法执行时 执行上下文栈的变化以下
ESCStack.push(<checkScope> function-Context)
ESCStack.pop()
ESCStack.push(<fn> function-Context)
ESCStack.pop()
复制代码

JavaScript函数执行时用到做用域链,做用域链是在函数定义时建立的。

执行上下文的重要特性

  1. 变量对象 Variable Object
  2. 做用域链 Scope Chain
  3. this

变量对象 Variable-Object

变量对象是与执行上下文相关的数据做用域,存储在上下文中定义的变量和函数声明。

全局执行上下文中的变量对象就是全局对象,在浏览器中全局对象就是window对象。

在函数执行上下文中,用**活动对象(Activation-Object)**表示比变量对象。互动对象在进入函数执行上下文时被建立,它经过函数的arguments属性初始化。

变量对象包括函数的全部形参、函数声明(function)、变量声明(var)。若是变量名称和已经声明的形参或函数名称相同,变量声明不会干扰已经存在的这类属性。

做用域链 Scope-Chain

做用域链保证对执行上下文有权访问的全部变量和函数的有序访问。

做用域的前端,始终是当前执行代码所在执行环境的变量对象;做用域的最后一个对象,始终是全局执行上下文的变量对象。

标识符解析是从做用域链的前端开始,逐层向上搜索标识符的过程。

相关文章
相关标签/搜索