严格模式是执行约束开关,不改变语法能力但提升错误检测:未声明赋值报错、this为undefined、禁止with等;需首行声明,作用域限定于脚本或函数,ES6模块自动启用。
它不改变 JavaScript 的能力,只改变引擎对代码的“容忍度”:原本静默忽略的问题,会直接报错。比如未声明就赋值——非严格模式下自动挂到 window 上;严格模式下立刻抛出 ReferenceError: username is not defined。
"use strict";,不是命令也不是函数调用,浏览器不支持时会被忽略(无副作用)
域分两级:整个脚本顶部写,全局生效;函数体第一行写,仅该函数内生效.mjs 或 import/export 文件)和 class 内部自动启用严格模式,无需手动加严格模式真正价值在于把“运行时才崩”的问题,变成“一写就报错”或“一跑就停”,大幅缩短调试链路。
count = 42; 在非严格模式下创建 window.count;严格模式下直接报错this 是 undefined 而非 window,避免意外修改全局对象{x:1, x:2})、重复函数参数(function foo(a, a) {})都会立即报 TypeError 或语法错误虽然现代构建工具(如 Webpack、Vite)和模块系统默认启用,但仍有真实场景依赖显式声明:
.js 文件未转模块,仍走 script 标签加载,必须靠 "use strict"; 触发arguments.callee 被禁用)if (true) {"use strict";} 无效,必须是脚本/函数的**物理首行**"use strict";
function test() {
"use strict";
undeclared = "boom"; // ReferenceError
this.x = 1; // 正常,因为 this 是 undefined,赋值被忽略(但不会报错)
return this;
}
test(); // 返回 undefined,而非 window
严格模式不是万能补丁,有些行为变化反而会让旧代码直接失效,上线前必须验证:
with 语句被完全禁止,任何含 with(obj) { ... } 的代码会直接 SyntaxError010)非法,必须写成 0o10 或 0x10
eval 变得更干净:它内部声明的变量不会泄露到外层作用域,但也不能通过 eval 动态创建函数参数或函数名class、enum、export、import、super)在严格模式下不能再当变量名,否则 SyntaxErrorimport 进来的模块也受约束;一个函数开了,不代表它的回调函数自动继承。这点在混合使用 CommonJS 和动态 eval 时尤其容易翻车。