12k
All articles

在现代 JavaScript 中使用严格模式的好处

JavaScript 严格模式规则、ESM 自动启用机制以及更安全的 this 绑定,有助于预防错误并更从容地调试旧有代码。

OpenReplay Team
OpenReplay Team
在现代 JavaScript 中使用严格模式的好处

如果你在 2025 年编写 JavaScript,你可能已经在不知不觉中使用了严格模式。ES 模块和类体会自动启用它。那么,为什么你还需要关心理解 JavaScript 严格模式呢?

因为遗留代码仍然存在。因为打包工具的配置各不相同。而且因为了解为什么某些错误会出现——而其他错误不会——会让你成为更好的调试者。

本文将解释 ECMAScript 严格模式的作用、哪些好处在今天仍然重要,以及你何时真正需要考虑它。

核心要点

  • 严格模式是 ES5 引入的 JavaScript 受限变体,它会将静默失败转换为错误,并禁止使用令人困惑的语法
  • ES 模块和类体会自动启用严格模式——你无法选择退出
  • 主要好处包括更早的错误检测、更安全的 this 语义以及隔离的 eval() 作用域
  • 显式的 "use strict" 对于遗留代码库、非模块脚本以及面向旧运行时的库仍然很重要

什么是 JavaScript 严格模式以及它存在的原因

JavaScript 严格模式是在 ECMAScript 5(2009 年)中引入的语言受限变体。你可以通过在脚本或函数顶部放置 "use strict" 来启用它。

这个指令存在是因为 JavaScript 早期设计包含了一些有问题的行为,这些行为无法在不破坏现有网站的情况下被移除。严格模式提供了一条通往更安全语义的可选路径。

在严格模式下,JavaScript 引擎会:

  • 将静默失败转换为抛出错误(例如给未声明的变量赋值)
  • 禁止使用令人困惑的语法(例如 with 语句)
  • 改变在没有上下文的情况下调用函数时 this 的行为
  • 防止意外创建全局变量

这些改变通过在开发时而非生产环境中暴露错误来支持 JavaScript 错误预防。

严格模式自动应用的场景

以下是许多开发者会忽略的内容:JavaScript ESM 严格模式是隐式的。当你使用 ES 模块(带有 import/export 的文件)时,严格模式始终启用。你无法选择退出。

同样适用于:

  • 类体:所有在 class 声明内的代码都在严格模式下运行
  • Node.js 中的 ES 模块:带有 .mjs 扩展名或在 package.json 中设置 "type": "module" 的文件

如果你的整个代码库使用 ES 模块和现代类语法,你已经在获得严格模式的好处。显式的 "use strict" 指令变得多余。

今天仍然重要的好处

即使严格模式通常是自动的,理解它的保护机制可以帮助你编写更好的代码并更快地调试。

更早的错误检测

严格模式将静默失败转换为抛出的错误。给未声明的变量赋值会抛出 ReferenceError 而不是创建意外的全局变量。给只读属性赋值会抛出 TypeError 而不是静默失败。

这在调试压缩的生产代码或使用第三方库时很重要。

更安全的 this 语义

在非严格模式下,在没有上下文的情况下调用函数会将 this 绑定到全局对象。在严格模式下,thisundefined。这可以防止意外修改全局对象——这是难以追踪的错误的常见来源。

隔离的 eval() 作用域

严格模式阻止 eval() 将变量引入到周围的作用域中。在 eval() 内声明的变量会保持在 eval() 内部。这减少了安全风险和意外的副作用。

限制和常见陷阱

严格模式不是万能的。有几个值得了解的注意事项:

函数级严格模式与某些参数语法冲突。 你不能在具有默认参数、剩余参数或解构参数的函数内使用 "use strict"。引擎会抛出 SyntaxError

混合严格和非严格代码是可能的。 当你连接脚本或加载第三方代码时,应用程序的不同部分可能在不同模式下运行。这可能导致微妙的行为差异。

浏览器控制台默认不使用严格模式。 在 DevTools 中测试代码片段可能会产生与实际应用程序不同的结果。

JavaScript 严格模式 vs. React StrictMode

这是完全不同的两个东西。JavaScript 严格模式是影响解析和运行时行为的语言级特性。React 的 <StrictMode> 是一个开发工具,用于突出显示 React 组件中的潜在问题——双重调用某些生命周期方法、检测已弃用的 API 以及警告副作用。

不要混淆它们。它们服务于不同的目的并在不同的层面运行。

何时你仍应关心严格模式

在 2025 年,显式的 "use strict" 主要在以下场景中重要:

  • 遗留代码库尚未迁移到 ES 模块
  • 非模块脚本通过 <script> 标签加载且没有 type="module"
  • 面向旧运行时的库,其中不保证支持模块
  • 混合模块系统,CommonJS 和 ES 模块共存

如果你正在维护旧代码或构建具有广泛兼容性的库,理解严格模式可以帮助你在迁移过程中避免微妙的错误。

结论

JavaScript 严格模式在现代开发中既不新鲜也不是可选的——它是 ES 模块和类中的默认行为。显式指令主要对遗留脚本和非模块环境重要。

真正的价值在于理解严格模式防范什么:静默失败、意外的全局变量和不安全的 this 绑定。这些知识使你在调试时更快,对代码质量更加谨慎,无论你是否亲自输入过 "use strict"

常见问题

我需要在每个 JavaScript 文件中添加 'use strict' 吗?

不需要。如果你使用 ES 模块(带有 import/export 语句的文件)或在类体内编写代码,严格模式会自动启用。你只需要在通过传统 script 标签加载的非模块脚本或使用遗留 CommonJS 代码时使用显式指令。

严格模式会破坏我现有的代码吗?

可能会。依赖于严格模式禁止的行为的代码——例如使用未声明的变量、with 语句或八进制字面量——将会抛出错误。在遗留项目中启用严格模式之前,请彻底测试以识别任何依赖于非严格行为的代码。

为什么我的浏览器控制台的行为与我的应用程序不同?

浏览器开发者控制台通常默认在非严格模式下运行。这意味着你在 DevTools 中测试的代码片段可能与在基于 ES 模块的应用程序中运行的相同代码表现不同。始终在实际应用程序环境中测试关键逻辑。

JavaScript 严格模式和 React StrictMode 有什么区别?

它们毫无关联。JavaScript 严格模式是改变引擎解析和执行代码方式的语言特性。React StrictMode 是一个组件,用于在开发期间帮助识别 React 应用程序中的潜在问题,例如已弃用的生命周期方法或意外的副作用。

Open-source session replay

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.