ESM默认启用严格模式,无需手动添加"use strict";只要使用import/export或.mjs扩展名,模块即强制运行于严格模式,自动拦截未声明变量赋值、重复参数名等错误。

ESM(ECMAScript Module)中严格模式默认启用,无需手动写 "use strict"。这个特性本身就能帮你避开不少老式脚本中容易忽略的语法陷阱,关键在于理解它“自动生效”的边界和配套实践。
ESM 默认开启严格模式的实质
只要文件使用 import 或 export,或以 .mjs 为扩展名,该模块就自动运行在严格模式下。这不是“建议”,而是语言规范强制行为——你无法关闭它。
- 函数内部不用再加
"use strict",也不用担心遗漏 - 全局作用域、顶层函数、箭头函数、类方法……全部受严格规则约束
- 即使模块里没写任何
import/export,只要被其他 ESM 导入,也会被纳入严格环境
自动规避的 4 类典型陷阱
这些错误在传统 script 标签中常被忽略,但在 ESM 中会立即报错,迫使你写出更干净的代码:
-
未声明变量赋值:比如
count = 10直接报ReferenceError,逼你用let count = 10 -
重复参数名:函数定义
function foo(a, a) { }在 ESM 中直接 SyntaxError,杜绝歧义调用 -
静默失败的 delete:对普通变量或函数执行
delete x会抛出TypeError,而不是默默返回false -
this 指向更可预测:顶层函数中的
this是undefined,不会意外绑定到window,避免隐式全局污染
仍需主动注意的“盲区”
严格模式虽默认开启,但有些陷阱不会自动拦截,需配合编码习惯:
-
八进制字面量依然报错:
010不合法,必须写成0o10或parseInt("10", 8) - with 语句完全禁止:哪怕只在局部用,ESM 下直接解析失败,得改用解构或显式属性访问
-
对象属性重复键名不报错:如
{x: 1, x: 2}在严格/非严格下都合法(后者取后一个),需靠 ESLint 规则no-dupe-keys补位 -
eval 和 arguments 受限但不禁止:它们仍是保留字,不能用作变量名,且
arguments.callee访问会报错
工程中强化效果的实用建议
借助 ESM 的默认严格性,把防御做在工具链里:
- 在
package.json中设"type": "module",让所有.js文件按 ESM 解析 - 用 ESLint 配合
env: { es2022: true, node: true },让它识别 ESM 环境并推荐现代写法 - 避免在 ESM 文件顶部拼接非模块脚本(如 UglifyJS 合并时混入旧代码),防止
"use strict"指令错位干扰 - 对动态导入的模块(
await import('./legacy.js')),确认其本身也符合 ESM 规范,否则可能降级为非严格上下文










