JS 的词法作用域

什么是作用域

负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。管理引擎如何在当前作用域以及嵌套的子作用域中根据标识符名称进行变量查找

在《你不知道的 JavaScript(上卷)》中的 1.2 章节《理解作用域》中有对编译原理进行简单描述。通过分析引擎、编译器、作用域如何协作来执行一段代码,讲解作用域

词法作用域

JavaScript 采用词法作用域(lexical scoping),也就是静态作用域。 简单地说,词法作用域就是定义在词法分析阶段的作用域。换句话说,词法作用域是由你在写代码时将变量和块作用域写在哪里来决定的,因此当词法分析器处理代码时会保持作用域不变。

看看下面实际的例子🌰

var value = 1;

function foo() {
    console.log(value);
}

function bar() {
    var value = 2;
    foo();
}

bar();

// 结果是 1

执行 foo 函数,先从 foo 函数内部查找是否有局部变量 value,如果没有,就根据书写的位置,查找上面一层的代码,也就是 value 等于 1,所以结果会打印 1。

简单的认识一下动态作用域

bash 就是动态作用域,把下面代码 bash 执行打印的值是 2。

value=1
function foo () {
    echo $value;
}
function bar () {
    local value=2;
    foo;
}
bar

在 bash 中执行 foo 函数时,依然是从 foo 函数内部查找是否有局部变量 value