在学习 JavaScript 中,我们不可避免地会遇到两种查询,即 LHS (Left Hand Side)和 RHS(Right Hand Side),可这两兄弟存在感很低,我们似乎在开发中很少接触过它们。
如果你这两种查询可有可无,那你就错了。任何编程语言都符合「达尔文进化论」的思想,一些不好的旧东西总是会慢慢被淘汰,而真正有用的往往会被保留下来,JavaScript 亦是如此。
所以 LHS 和 RHS 是有价值的,只是我们还没挖掘出来而已。
LHS 和 RHS 的含义
如果你已经掌握或者对这两种查询无感,那么可以跳过,直接看作用篇。如果你还是小白,希望你不要错过~
LHS 和 RHS 简单来说是一个赋值操作的左侧和右侧,L 就代表 Left 左侧,R 就是代表 Right 右侧啦。
不过这样说还是会有很多小伙伴不好理解,没关系,接下来我举几个例子之后,你就会恍然大悟。
LHS 查询通常就是赋值操作,如:
a = 2;
b = "bbb";
c = {};
像这种为 = 2
这个赋值操作找到目标变量的过程,就是 LHS 查询,其实就是简单的赋值。
再来看看 RHS,先来个例子
console.log(a)
当程序运行到这里,会遇到变量 a
,但此时程序并不知道 a
的值是多少,所以需要查找并取得 a
的值,这样才能传递给程序进入输出操作。
这种查询过程就是 RHS 查询,我们可以简单理解为:寻找某个变量的源值。
LHS 和 RHS 的作用
那为什么要区分这两种查询呢?因为它能帮助我们正确地识别 JavaScript 程序运行中抛出的异常类型。
我们常见的异常类型有 Error
、 SyntaxError
、TypeError
、ReferenceError
、RangeError
...
其中属 TypeError
、ReferenceError
最为常见并且十分重要,而这两个异常类型却和 LHS、RHS 有着千丝万缕的联系
ReferenceError
表示引用错误,当 JavaScript 在作用域中找不到目标变量时,就会抛出这种错误,如
console.log(a)
如果我们没有定义
a
这个变量,就会抛出ReferenceError: a is not defined
的错误,这是 RHS 查询失败引起的错误,因为找不到源值a
TypeError
表示类型错误,目标变量在作用域中是存在的,但对该变量的操作是非法的、不合理的,如:
var f = 1;
f();
因为
f
并不是一个函数,但我们仍然以函数的形式引用它,这时候就会抛出TypeError: f is not a function
的错误,这说明变量f
找到了,但我们对它使用了非法操作。
总结来了
-
在非严格模式下,RHS 引用不成功(找不到目标变量),就会导致抛出
ReferenceError
异常。 -
在非严格模式下,当执行 LHS 查询,如果在作用域中找不到目标变量,全局作用域会自动创建一个相同名称的变量,就是我们所说的声明提前,返回给 JS 引擎,并且该值为
undefined
。但如果是在严格模式下,执行上述操作,也会抛出ReferenceError
异常。因为在严格模式下,是禁止自动或隐式地创建全局变量的。 -
如果 RHS 查询找到一个变量,但你对该变量进行不合法的操作,如调用一个非函数类型的值,或者引用
null
或undefined
中的属性,会抛出另一种异常,TypeError
这样一来,当抛出 ReferenceError
或者 TypeError
异常时,我们就能快速定位问题所在,判断该错误是 LHS 还是 RHS 引起的了。