为什么你的 JS 代码有时崩溃有时侥幸运行?LHS/RHS 的“潜规则”全解析

JavaScript中的LHS与RHS查询:为什么有的代码会报错,有的却不会?

在 JavaScript 中,变量的查找机制分为 LHS(Left-Hand Side)查询RHS(Right-Hand Side)查询。这两种查询方式在作用域中的行为不同,直接影响了代码是否会抛出错误。本文将通过两个示例代码,详细解释它们的区别。


示例1:RHS查找失败导致报错

javascript 复制代码
function foo(a) {
  console.log(a + b); // RHS查找b失败,报错!
  b = a;
}
foo(2); // 报错:ReferenceError: b is not defined

在这段代码中,函数 foo 试图在 console.log(a + b) 中计算 a + b 的值。此时,引擎会对变量 b 进行 RHS查询 (即查找 b 的值)。然而,在 foo 的作用域内,b 尚未被定义,且全局作用域中也没有 b 的声明。此时 RHS 查找失败,引擎直接抛出 ReferenceError 异常,代码终止执行。

关键点

  • RHS 查询的目的是获取变量的值,失败时会抛出错误。
  • 代码中 b = a 位于 console.log 之后,因此还未执行到这一步,b 未被赋值。

示例2:LHS隐式创建全局变量

javascript 复制代码
function foo() {
  b = 2; // LHS查找b失败,自动创建全局变量!
}
foo();
console.log(b); // 输出2(全局变量生效)

在这段代码中,函数 foo 内部对 b 进行了赋值操作 b = 2。引擎此时会进行 LHS查询 ,尝试找到变量 b 的位置以便赋值。由于当前作用域(foo 内部)和上层作用域(全局)中均未声明 b,在非严格模式下,引擎会隐式地在全局作用域中创建一个全局变量 b 并赋值为 2。因此后续的 console.log(b) 可以正常输出。

关键点

  • LHS 查询的目的是找到变量容器本身(赋值的目标位置),失败时在非严格模式下会隐式创建全局变量。
  • 严格模式("use strict")下,LHS 失败也会抛出 ReferenceError

LHS 与 RHS 的核心区别

  1. 目的不同

    • RHS :查找变量的值(如 console.log(a) 中的 a)。
    • LHS :查找变量容器本身(如 a = 3 中的 a),以便赋值。
  2. 失败时的行为

    • RHS 失败 :直接抛出 ReferenceError
    • LHS 失败(非严格模式):自动在全局作用域创建变量。
    • LHS 失败 (严格模式):同样抛出 ReferenceError
  3. 作用域链的查找机制

    • 两种查询都会沿着作用域链逐级向上查找,直到全局作用域。
    • RHS 失败时立即终止;LHS 失败时(非严格模式)在全局作用域"兜底"。

严格模式下的差异

在严格模式("use strict")中,LHS 的行为会发生变化:

javascript 复制代码
"use strict";
function foo() {
  b = 2; // LHS失败,严格模式下报错!
}
foo(); // ReferenceError: b is not defined

严格模式禁止自动创建全局变量,因此 LHS 查找失败时也会抛出错误,与 RHS 行为一致。


总结

  • RHS 失败必报错:因为引擎需要获取变量的值,找不到时无法继续执行。
  • LHS 失败可能隐式创建变量(仅在非严格模式):这一特性可能导致意外的全局变量污染,需谨慎使用。
  • 推荐使用严格模式:避免隐式全局变量,提升代码安全性。

理解 LHS 和 RHS 的机制,能帮助我们更好地调试作用域相关的问题,并写出更健壮的代码。

相关推荐
花菜会噎住1 小时前
Vue3核心语法进阶(computed与监听)
前端·javascript·vue.js
I'mxx1 小时前
【vue(2)插槽】
javascript·vue.js
花菜会噎住1 小时前
Vue3核心语法基础
前端·javascript·vue.js·前端框架
全宝1 小时前
echarts5实现地图过渡动画
前端·javascript·echarts
吃饭睡觉打豆豆嘛3 小时前
彻底搞懂前端路由:从 Hash 到 History 的演进与实践
前端·javascript
lbh4 小时前
简单文本编辑器:基于原生JavaScript的智能文本选择工具栏
前端·javascript
典学长编程4 小时前
前端开发(HTML,CSS,VUE,JS)从入门到精通!第三天(JavaScript)
前端·javascript·css·html·前端开发
Jimmy6 小时前
TypeScript 泛型:2025 年终极指南
前端·javascript·typescript
Spider_Man6 小时前
栈中藏玄机:从温度到雨水,单调栈的逆袭之路
javascript·算法·leetcode
jstart千语7 小时前
【vue】创建响应式数据ref和reactive的区别
前端·javascript·vue.js