作用域是一套存储变量的规则,程序读写可以很方便的找到这些变量的位置
传统语言编译过程
A--分词/词法分析:字符分解为词法单元
B--解析/语法分析:将词法单元流构成语法树
C--代码生成:讲语法树生成目标平台能运行的代码
js语言编译过程
引擎:从头至尾的编译和执行过程
编译器:语法分析和代码生成====>>代码生成阶段和传统编译出现差异化。
作用域:收集/维护所有声明的标识符组成的一系列查询,实施一套规则, 确定当前执行代码对这些标识符的访问权限。
编译器处理
声明变量
=>查询当前作用域
=>存在同名声明
> 忽略声明
声明变量
=>查询当前作用域
=>·不·存在同名声明
> 声明变量
生成运行代码
引擎处理
询问当前作用域
=>存在变量
=>赋值使用
询问当前作用域
=>不存在变量
=>查询赋值
tips:引擎查询
RHS 查询与简单地查找某个变量的值别无二致,而 LHS查询则是试图找到变量的容器本身,从而可以对其赋值。从这个角度说,RHS 并不是真正意义上的“赋值操作的右侧”,更准确地说是非左侧
这段话理解起来其实有点读经书,看起来字面意思很简单,但实际上好像又不是那么回事。有段解释是这样说的:【概念上最好将其理解为“赋值操作的目标是谁(LHS)”以及“谁是赋值操作的源头(RHS)”】。
console.log(a)
//这里进行的是RHS查询【寻找源】,如果在没有定义a的情况下,会出现未定义的异常
var a=2;
//这里其实进行的是LHS查询【寻找容器】,确认a是否存在,然后再出现赋值2的操作
作用域嵌套
当一个函数嵌套另一个函数中时,就发生了作用域嵌套。
LHS 和 RHS 引用都会在当前作用域进行查找,如果没有找到,就会去上一层查找,以此类推。一旦抵达全局作用域,可能找到所需变量,也可能没找到,但无论如何查找过程都将停止。