参考资料:
作用域和闭包
演员表:
首先介绍将要参与到对程序var a = 2;
进行处理的过程中的演员们,这样才能理解接下来将要听到的对话。
- 引擎
从头到尾负责整个JavaScript程序的编译及执行过程。
- 编译器
引擎的好朋友之一,负责语法分析及代码生成等脏活累活(详见前一节的内容)。
- 作用域
引擎的另一位好朋友,负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。
为了能够完全理解JavaScript的工作原理,你需要开始像引擎(和它的朋友们)一样思考,从它们的角度提出问题,并从它们的角度回答这些问题。
📚作用域
作用域是一套规则,用于确定在何处以及如何查找变量(标识符)。如果查找的目的是对变量进行赋值,那么就会使用LHS查询;如果目的是获取变量的值,就会使用RHS查询。赋值操作符会导致LHS查询。=操作符或调用函数时传入参数的操作都会导致关联作用域的赋值操作。
JavaScript引擎首先会在代码执行前对其进行编译,在这个过程中,像var a = 2这样的声明会被分解成两个独立的步骤: 1.首先,var a在其作用域中声明新变量。这会在最开始的阶段,也就是代码执行前进行。 2.接下来,a = 2会查询(LHS查询)变量a并对其进行赋值。 LHS和RHS查询都会在当前执行作用域中开始,如果有需要(也就是说它们没有找到所需的标识符),就会向上级作用域继续查找目标标识符,这样每次上升一级作用域(一层楼),最后抵达全局作用域(顶层),无论找到或没找到都将停止。 不成功的RHS引用会导致抛出ReferenceError异常。不成功的LHS引用会导致自动隐式地创建一个全局变量(非严格模式下),该变量使用LHS引用的目标作为标识符,或者抛出ReferenceError异常(严格模式下)。
📝练习:
function foo(a) {
var b = a;
return a + b;
}
var c = foo(2);
1.找到其中所有的LHS查询。(这里有3处!)
2.找到其中所有的RHS查询。(这里有4处!)
答案```
- 不能重复声明
- 有块级作用域
| let | var | |
| —- | —- | —- |
|
1. 不能重复声明
|
1. 可以重复声明
| 命名空间的影响 | |
2. 有块级作用域
|
2. 有函数作用域
| 时代的进步(更新,更符合逻辑) | |
3. 不存在变量提升
|
3. 存在变量提升
| 提升的意义:性能吗?
——见[你不知道的js上]第一部分,第4章 | |
4. 不影响作用域链
| | |
📚作用域闭包
测试折叠块拖拽: 我是块2
我是块1
我是块3