一、什么是LHS、RHS
1、RHS 查询与简单地查找某个变量的值别无二致,即谁是赋值操作的源头
2、 LHS 查询则是试图找到变量的容器本身,从而可以对其赋值。(从这个角度说,RHS 并不是真正意义上的“赋值操作的右侧”,更准确地说是“非左侧”。)即赋值操作的目标是谁
注:可以将 RHS 理解成 retrieve his source value(取到它的源值),这意味着“得到某某的值”。
3、RHS:
console.log(a)
- 对 a 的引用是一个 RHS 引用,因为这里 a 并没有赋予任何值。
- 需要查找并取得 a 的值,这样才能将值传递给 console.log(..)
4、LHS:
a = 2;
- 对 a 的引用则是 LHS 引用,因为实际上我们并不关心当前的值是什么,只是想要为 = 2 这个赋值操作找到一个目标
5、既有 LHS 也有 RHS 引用
function foo(a) { // 当参数2传进来时,LHS
console.log( a ); // 2,RHS引用
}
foo( 2 ); // foo(..) 函数的调用需要对 foo 进行 RHS 引用
- foo(..) 函数的调用需要对 foo 进行 RHS 引用,意味着“去找到 foo 的值,并把它给我”。并且 (..) 意味着 foo 的值需要被执行
- 在 2 被当作参数传递给foo(..) 函数时,2 会被分配给参数 a。为了给参数 a(隐式地)分配值,需要进行一次LHS 查询。
- 对 a 进行的 RHS 引用,并且将得到的值传给了 console.log(..)。console.log(..) 本身也需要一个引用才能执行,因此会对 console 对象进行 RHS 查询,并且检查得到的值中是否有一个叫作 log 的方法
二、异常
在变量还没有声明(在任何作用域中都无法找到该变量)的情况下,LHS 查询 和 RHS 查询的行为是不一样的:
- 如果 RHS 查询在所有嵌套的作用域中遍寻不到所需的变量,引擎就会抛出 ReferenceError异常。
- 在非“严格模式”下,当引擎执行 LHS 查询时,如果在顶层(全局作用域)中也无法找到目标变量,全局作用域中就会创建一个具有该名称的变量,并将其返还给引擎
- 在严格模式中, LHS 查询失败时,并不会创建并返回一个全局变量,引擎会抛出 ReferenceError 异常。(严格模式禁止自动或隐式地创建全局变量)
- 如果 RHS 查询找到了一个变量,但是你尝试对这个变量的值进行不合理的操作,比如试图对一个非函数类型的值进行函数调用,或着引用 null 或 undefined 类型的值中的属性,那么引擎会抛出另外一种类型的异常,叫作 TypeError
注:
- ReferenceError 同作用域判别失败相关,
- TypeError 代表作用域判别成功了,但是对结果的操作是非法或不合理的
三、小结
查询类型 | 目的 | 实例 | 查询方向 | 异常及处理 |
---|---|---|---|---|
RHS | 获取变量的值 | console.log(a) | 在当前执行作用域中开始,如果没有找到所需的标识符,就会向上级作用域继续查找,最后抵达全局作用域(顶层),无论找到或没找到都将停止 | ReferenceError |
LHS | 对变量进行赋值 | a = 2; | 同RHS | ①、严格模式下:ReferenceError ②、非严格模式下:自动隐式地创建一个具有该名称的全局变量 |