一、作用域是什么 (学习笔记)—— 《你不知道的JavaScript》

 

因为全部都是文字不太好理解,所以尽可能地把所有的文字都画成了图,便于理解。

作用域是什么

传统编译流程:

 

JavaScript 引擎会在语法分析和代码生成阶段,通过特定的步骤,对运行性能进行优化。包括冗余元素优化等。

JavaScript 编译,大部分情况下,发生在代码执行前的几微妙(甚至更短)。

 

理解作用域

引擎、编译器、作用域

 

var a = 1;

 

以上代码,经历了两个不同的声明:

  • 编译器在编译时的处理
  • 引擎在运行时的处理

 以 var a = 1; 为例,演示引擎、编译器、作用域三者是如何工作的

 

变量的赋值操作会执行两个动作:1. 编译器在当前作用域中声明一个变量; 2. 运行时引擎在作用域中查找该变量,找到便赋值,找不到抛出异常。

 

LHS && RHS

先来张图,解释什么是 LHS、RHS

 

看下面代码,加深理解

console.log(a); // 对 a 的引用是 RHS 引用。因为没有对 a 赋值,而是查找并取得 a 的值。
a = 2; // 对 a 的引用是 LHS 引用。不用关心 a 的值是什么,只需要为 = 2 这个赋值操作找到一个目标。

 

引擎和作用域的对话

以下面代码为例:

function foo(a) {
    console.log(a);
}
foo(2);

 

 

小测验

把自己当做引擎,同作用域进行一次“对话”。

function foo(a) {
    var b = a;
    return a + b;
}
var c = foo(2);

 

1. 找到其中所有的LHS查询。(这里有3处!)

2. 找到其中所有的RHS查询。(这里有4处!)

 

作用域嵌套

当一个块或函数嵌套在另一个块或函数中时,就发生了作用域嵌套。因此,在当前作用域中无法找到该变量时,引擎会在当前嵌套的作用域的外层继续查找,直到找到该变量,或抵达最外层作用域(全局作用域为止)。

看以下代码:

function foo(a) {
    return a + b;
}

var b = 1;
foo(2);

对 b 进行的 RHS 引用无法在函数 foo 内部完成,但可以在上一级作用域(在这个例子中就 是全局作用域)中完成。

我们来模拟一下以上代码的引擎与作用域的对话。

 

注:以上所有的文字、代码都是本人一个字一个字敲上去的,图片也是一张一张画出来的,转载请注明出处,谢谢!