JS 作用域和作用域链

53 阅读2分钟

词法环境(Lexical Environments):一种规范类型,用于根据 ECMAScript 代码的词法嵌套结构来定义标识符与特定变量和函数的关联。

通俗来说,词法环境就是一套约定好的规则。我们写代码,应该按照这个规则来。JS引擎对JS源码进行词法分析,也是按照这个规则来。

词法环境,其实就是作用域。

结论:

  1. 在 js 中可将作用域定义为一套规则,用来管理 js 引擎如何在当前作用域以及嵌套的子作用域中根据标识符名称来进行变量查找。(这里的标识符指的是变量名或函数名)
  2. JS 中有全局作用域与函数作用域(暂不考虑 eval)
  • 一个词法环境,由环境记录( Environment Records )与一个外部指向 outer 组成。
  • 环境记录分为:函数环境记录、声明性的环境记录。
  • 而环境记录对应的,其实就是变量对象。
  • outer 对应的是 scopeChain。
  • 作用域是一套规则。
  • 而作用域链则是在代码执行过程中,会动态变化的一条索引路径。
  • 作用域链,是由当前环境与上层环境的一系列变量对象组成,它保证了当前执行环境对符合访问权限的变量和函数的有序访问。
var a = 20;
function test () {
  var b = a + 10;
  function innerTest () {
    var c = 10;
    return b + c;
  }
  return innerTest();
} 
test();

上面这段代码中 全局、函数test、函数innerTest 的执行上下文先后创建。 假设其对应的变量对象分别为 VO(global)、VO(test)、 VO(innerTest)。 而 innerTest 的作用域链,则同时包含了这三个变量对象,innerTest 的执行上下文如下:

innerTestEC = {
  VO: { ... },  // 变量对象  
  scopeChain: [VO(innerTest), VO(test), VO(global)], // 作用域链
}

以最前端为起点,最末端为终点的单方向通道。

image.png