编译过程
整个编译过程,️有3个重要角色,分别是: 引擎 从头到尾负责整个 javascript 程序的编译和执行过程。 编译器 负责语法分析及代码生成等 作用域 负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非常严格的规则,确认当前执行的代码对这些标识符的访问权限。
LHS和RHS
引擎在查找变量的时候,是通过 LHS 或者 RHS的方式去查找变量的。
比如以下代码:
var a = 2;
编译器在编译后生成可执行代码,引擎执行他的时候,会通过查找变量a是否已经声明过。其中上述例子,就是通过LHS方式就行查找的,简单记忆是 L 是left的意思,变量在 = 的left,就是LHS查找变量。
反之,不是LHS的就是RHS(不能理解为变量在=右边),比如以下代码:
console.log(a);
对变量a的查询过程,就是RHS。
为什么需要区分LHS和RHS
考虑以下代码:
function foo(a) { console.log( a + b ); b = a; }
foo( 2 );
第一次在对b进行RHS查询时,是无法找到该变量的,并且在外层作用域也找不到,此时引擎就会抛出错误 ReferenceError 。
相比之下,LHS在进行变量查询的时候,如果在顶层作用域中都找不到该变量声明,会自动给他创建一个具有该名称的变了,并将其返回给引擎。(前提是当前在非严格模式下)。
小结
- 整个编译过程,由 引擎, 编译器, 作用域 3大部分构成;
- 编译器编译后生成可执行代码,引擎查找变量的时候会由 LHS和RHS的区分,其中两种查询方式对于异常的处理方式不同。