JS-执行环境(Execution Context)和作用域(Scope)

什么是执行环境

简单来说,执行环境就是JavaScript代码被解析编译时所在的环境。执行环境定义了变量或者函数有权访问的其他数据,决定了它们各自的行为。每当函数调用的时候就会产生一个执行环境,每个执行环境都有一个与之关联的变量对象,执行环境中定义的额所有变量和函数都保存在这个对象中,在编写代码中并不能访问这个对象,但是代码解析器在处理时就会时用到它。

在JS中有三种不同类型的执行环境:

  • Global:全局执行环境
  • Function:函数执行环境
  • Eval:使用eval()函数执行的JS代码产生的执行环境

JS的实现是单线程的,也就是说在一个时间点只会处于一个执行环境中。在JS实现中所有的环境都在一个环境调用栈中,处于运行状态的执行环境永远处于栈顶,当有一个新执行环境就入栈,当执行结束就出栈。执行中相关变量的查找也基于该调用栈。

执行环境组成

每个执行环境由三部分构成:

  • 变量对象(Variable object):环境中定义的所有变量,执行环境是函数的话最开始只包含arguments对象,变量对象是开发者不可访问的
  • 作用域链(Scope Chain):作用域即变量对象,作用域链是一个通过调用栈由变量对象组成的带头结点的单向链表
  • this:指向一个环境对象

全局执行环境

全局执行环境时最外围的一个执行环境。根据ECMAScript实现所在的宿主环境不同,表示执行环境的对象也不一样。平时开发,在Web浏览器中,全局执行环境被认为时window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的。

当某个执行环境中的所有代码执行完毕后,该环境会被销毁,保存在其中的所有变量和函数定义也随之销毁。全局执行环境直到应用程序推出,比如关闭网页或者浏览器时,就会被销毁。

函数执行环境

每个函数都有自己的执行环境,当函数被调用时就会产生一个执行环境,并且该执行环境被推入环境栈中,在函数执行完毕之后,栈将该执行环境弹出,执行控制权返回到之前的执行环境。

什么是作用域

当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的最前端始终都是当前代码所在执行环境的变量对象。如果这个环境是函数,其活动对象作为当前执行环境的变量对象,该活动对象在最开始只包含arguments对象。作用域链中下一个变量对象来自当前环境栈中的前一个执行环境,以此类推直到全局执行环境。全局执行环境的变量对象始终都是作用域链中的最后一个变量对象。

let color = 'red';
function changeColor() {
    if(color === 'red') {
        color = 'blue';
    } else {
        color = 'red';
    }
}
changeColor();

在上面栗子中,函数changeColor的作用域链包含两个对象,一个是自己的变量对象,一个是全局环境的变量对象。

可以在函数的内部访问到变量color,因为能在作用域链上找到。

小结

  • 执行环境始终是this关键字的值,它是拥有当前所执行代码的对象的引用。每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。虽然编码中无法访问这个对象,但解析器在处理数据时会在后台使用它。
  • 作用域涉及到被调用函数中的变量访问,保证对执行环境有权访问的所有变量和函数的有序访问。
原文链接:juejin.im

上一篇:揭秘 Vite 的原理
下一篇:webpack升级之旅(2->4)

相关推荐

  • 高阶组件 + New Context API = ?

    1. 前言 继上次小试牛刀(https://github.com/SmallStoneSK/Blog/issues/6)尝到高价组件的甜头之后,现已深陷其中无法自拔。。。

    2 年前
  • 面试官:说说作用域和闭包吧

    几乎所有语言的最基础模型之一就是在变量中存储值,并且在稍后取出或修改这些值。在变量中存储值和取出值的能力,给程序赋予了状态。这就引伸出两个问题:这些变量被存储在哪里?程序如何在需要的时候找到它们?回...

    2 个月前
  • 闭包,this,作用域链,原型链

    参考书:《JavaScript高级程序设计 第3版》 参考博客:www.jianshu.com/p/f8c7c5502… 执行环境 执行环境是Javascript中最为重要的一个概念。

    8 天前
  • 闭包、作用域链

    1.说到闭包大家可能会说函数套函数,延长作用域链。对没错,确实是这样的,但是你对他的理解是多少呢,函数闭包可以说的有很多,夸张的说,说个半天是绝对没问题的,它的用处非常多,作用也非常多,这个需要你多想...

    1 年前
  • 重拾React: Context

    前言   首先欢迎大家关注我的Github博客(https://github.com/MrErHu/blog),也算是对我的一点鼓励,毕竟写东西没法获得变现,能坚持下去也是靠的是自己的热情和大家的...

    1 年前
  • 重学Javascript之变量,作用域及内存管理

    JavaScript变量及类型检测 javascript数据类型分为基本数据类型,引用数据类型和Symbol。 基本数据类型 String,Number,Boolean,undefined,...

    8 个月前
  • 通俗易懂介绍js作用域链和闭包,不懂的进!

    es5作用域 javascript作用域分为全局作用域和局部作用域。在全局作用域内定义的就是全局变量,即window对象上的局部变量;局部作用域是函数作用域,注意是函数作用域而不是大括号作用域 ...

    2 年前
  • 适用于 Vue 2.0 的功能强大的 Contextmenu 组件

    NPM(https://img.javascriptcn.com/321f8e0d83788698c5e5898eec9a9844)(https://link.funteas.com?target=h...

    3 年前
  • 还是不明白JavaScript - 执行环境、作用域、作用域链、闭包吗?

    JavaScript中的执行环境、作用域、作用域链、闭包一直是一个非常有意思的话题,很多博主和大神都分享过相关的文章。这些知识点不仅比较抽象,不易理解,更重要的是与这些知识点相关的问题在面试中高频出...

    1 年前
  • 读书笔记:执行上下文(Execution Context)

    文章地址:https://github.com/leonardoms...(https://github.com/leonardomso/33jsconcepts1callstack) 浏览...

    2 年前

官方社区

扫码加入 JavaScript 社区