JavaScript中的LHS和RHS查询
Jun 19, 2016
编译原理
程序中的源代码在执行之前会经历三个步骤:
1、分词/词法分析;
2、解析/语法分析(此步骤包含AST);
3、代码生成;
LHS 和 RHS
Example:
1 | var a = 2 |
编译器会做如下处理:
1、
var a
编译器会询问作用域是否已经存在该名称的变量,如果存在,编译器会忽略该声明,否则在当前作用域中声明一个新的变量,命名为a
。2、
a = 2
赋值操作,会询问当前作用域是否存在a
变量,如果存在使用当前变量进行赋值操作。
我们的例子中,引擎会为变量a
进行LHS
查询,另一个查找类型叫做RHS
。
LHS
和RHS
的含义是‘赋值操作的左侧或右侧’,并不意味着就是=
赋值操作符的左侧或右侧,赋值操作还有其他几种形式。概念上最好理解为“赋值操作的目标是谁(LHS)” 以及 “谁是赋值操作的源头(RHS)”。
为什么区分LHS和RHS很重要
考虑以下代码:
1 | function foo (a) { |
第一次对
b
进行RHS
查询时是无法找到该变量的,这是一个“未声明”的变量。如果RHS
在所嵌套的作用域中找不到该变量,就会抛出ReferenceError
异常,当引擎进行
LHS
查询时,如果在嵌套的作用域中直至全局作用域中也无法找到目标变量,如果不是严格模式下,就会在全局作用域中创建一个该名称的变量。
LHS和RHS 顺序影响理解
变量提示
、作用域
、This
等
Reference: You Don’t Know JS: Scope & Closures