《你不知道的JavaScript》随记---对LHS 和 RHS 查询的理解

142 阅读4分钟

在 JavaScript 开发中,LHS 和 RHS 是两个绕不开的概念。

对此,《你不知道的JavaScript》此书中的解释是:

当变量出现在赋值操作的左侧时进行LHS查询,出现在右侧时进行RHS查询。

RHS查询与简单地查找某个变量的值别无二致,而LHS查询则是试图找到变量的容器本身,从而可以对其赋值。

我的理解是:它们就像程序运行时的“找人”过程——一个负责“找谁放值”,一个负责“找谁要值”。

下面,我将通过我的理解,再结合一些案例简单说说。


一、LHS 和 RHS 到底是啥?

1. LHS 查询(Left-Hand Side)

LHS 查询的目标是找到变量的容器,以便进行赋值操作。

换句话说,LHS 查询关注的是“变量存储的位置变量的初始化”。

典型使用场景

  • 变量赋值:var a = 10;
  • 参数传递:function foo(a) { ... }

2. RHS 查询(Right-Hand Side)

RHS 查询的目标是获取变量的值,以便用于计算或传递。

RHS 查询关注的是“变量值的查询和传递”。

典型使用场景

  • 使用变量:console.log(a);
  • 函数调用:foo();

二、在实际开发应用中的使用

话不多说,先来两个案例,请找出其中的LHS查询和RHS查询。

例1:

function foo(a) {
  console.log(a); 
}
foo(2); 

答案:

LHS 查询有:

  • foo ( 2 ) , 隐式 LHS 查询:相当于var a = 2,对a进行初始化

RHS 查询有:

  • console.log(a) , RHS 查询 a 的值并输出

例2:

function foo(a) {
  var b = a; // LHS 查询 b,RHS 查询 a
  return a + b; // RHS 查询 a 和 b
}
var c = foo(2); // LHS 查询 c,RHS 查询 foo(2)

答案:

LHS 查询有:

  • var b = ..., 对b的初始化
  • var c = ..., 对c的初始化
  • ... = foo(2), 隐式 LHS 查询:相当于var a = 2,对形参a进行初始化

RHS 查询有:

  • ... = a , 查询a的值并传递(给b
  • return a + b,查询a的值和b的值并返回。
  • ... = foo(2)查询 foo(2)的值并传递(给c)

现在,你或许大致对LHS和RHS的使用有个大致的了解,这时,你再回过头来看这几句话:

  • LHS 查询关注的是“变量存储的位置变量的初始化

  • RHS 查询关注的是“变量值的查询和传递”。

  • RHS查询负责查找某个变量的值,而LHS查询则负责找到变量的容器本身,然后把RHS查询到的值赋值进去。

此时,你是否有了不一样的感悟?

小贴士:

例2中:

var b = a

var c = foo(2)

在这种变量声明和赋值过程中,LHS 和 RHS 会交替出现。


三、一点小小的扩展

1. ## 变量不存在时的行为

查询类型非严格模式严格模式
LHS自动给你创建一个全局变量直接甩锅:ReferenceError
RHS返回 undefined同样甩锅:ReferenceError

举一个栗子

// 非严格模式下,LHS 会偷偷给你造个变量
a = 10; // a 会变成全局变量,别慌!

// 严格模式下,LHS 就很刚
function bar() {
  'use strict';
  a = 10; // 报错:a is not defined(不给你自动创建了!)
}

2. RHS 查询失败的后续影响

  • ReferenceError:变量未声明时抛出。
  • TypeError:变量已声明但无法进行预期操作时抛出(如调用非函数值或访问 null/undefined 的属性)。

举两个栗子

// RHS 查不到变量?直接报错
console.log(b); // ReferenceError: b is not defined

// RHS 找到变量但操作不对劲?
var c;
c(); // TypeError: c is not a function(c 是 undefined,没法调用)


四、踩坑指南:这些错误你遇到过吗?

1. 隐式全局变量污染

非严格模式下,忘记声明变量赋值会自动创建全局变量,容易造成命名冲突。

解决办法

  • 开启严格模式('use strict';),让错误显性化。
  • 始终用 let/const/var 显式声明变量。

2. RHS 查询失败的连锁反应

未声明变量的 RHS 查询可能导致程序崩溃。

解决办法

  • 在访问变量前进行检查(如 typeof a !== 'undefined')。
  • 使用默认值(如 || 或 ?? 运算符)。

五、LHS 和 RHS 对比总结

特性LHS 查询RHS 查询
目标找变量的存储位置(初始化)获取变量的值(使用)
失败行为(非严格模式)自动创建全局变量返回 undefined
失败行为(严格模式)报错:ReferenceError报错:ReferenceError
典型场景变量赋值、参数传递变量读取、函数调用
异常关联隐式赋值失败 → ReferenceError变量未声明 → ReferenceError
操作非法 → TypeError

六、总结一下

LHS 和 RHS 其实就是 JavaScript 引擎在“找人办事”时的两种态度:一个是“我要把值放到谁身上”,另一个是“我要从谁身上取值”。

掌握它们的区别,不仅能帮你写出更稳定的代码,还能让你看懂那些“离谱”的报错信息。

以上为小编的个人理解,如有不对的地方,欢迎各位大佬在评论区指正!