为什么你的 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 的机制,能帮助我们更好地调试作用域相关的问题,并写出更健壮的代码。

相关推荐
东东51611 分钟前
基于vue的电商购物网站vue +ssm
java·前端·javascript·vue.js·毕业设计·毕设
MediaTea16 分钟前
<span class=“js_title_inner“>Python:实例对象</span>
开发语言·前端·javascript·python·ecmascript
雨季66638 分钟前
Flutter 三端应用实战:OpenHarmony “微光笔记”——在灵感消逝前,为思想点一盏灯
开发语言·javascript·flutter·ui·dart
编码者卢布1 小时前
【Azure Stream Analytic】用 JavaScript UDF 解决 JSON 字段被转成 Record 的关键点
javascript·json·azure
0思必得01 小时前
[Web自动化] Selenium执行JavaScript语句
前端·javascript·爬虫·python·selenium·自动化
tb_first2 小时前
SSM速通2
java·javascript·后端
摘星编程4 小时前
用React Native开发OpenHarmony应用:StickyHeader粘性标题
javascript·react native·react.js
A_nanda4 小时前
c# 用VUE+elmentPlus生成简单管理系统
javascript·vue.js·c#
天天进步20154 小时前
Motia事件驱动的内核:深入适配器(Adapter)层看消息队列的流转
javascript
北极糊的狐4 小时前
若依项目vue前端启动键入npm run dev 报错:不是内部或外部命令,也不是可运行的程序或批处理文件。
前端·javascript·vue.js