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

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

Execution Content 执行上下文

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

执行上下文分3种:

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

创建执行上下文

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

  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 定义的函数声明和变量绑定

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

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

变量环境 Variable-Environment

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

在创建阶段,let、const定义的变量变量没有关联任何值,但是var声明的变量会被设置为undefined,所以var变量在声明之前访问值为undefined,但不会报错,即变量声明提升。let、const变量声明前访问会导致引用错误。

执行阶段

执行阶段完成对所有变量的分配,并执行代码。

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

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

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

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

转载于:https://juejin.im/post/5c20f571e51d452429742b45

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值