讲解
严格模式是 ES5 引入的一套更严格的 JavaScript 运行规则:在脚本或函数顶部写 'use strict' 开启。它把一批「静默失败」的坏写法变成显式报错,把一批危险语法直接禁用,目的是让错误在开发期就爆炸,而不是在生产环境埋下诡异的 bug。ES6 模块(type="module" 或 .mjs)和 class 内部的代码自动是严格模式,无需手动开启——现代代码其实一直跑在严格模式下。
严格模式的主要变化:给未声明的变量赋值会抛 ReferenceError(非严格模式会悄悄创建全局变量);静默失败的赋值(改只读属性、改不可写配置)会抛 TypeError;普通函数独立调用时 this 是 undefined 而不是全局对象;禁用 with 语句;函数参数不允许重名;八进制字面量(0123)报错;delete 变量报错;eval 有自己的作用域不再污染外层。这些变化的共同点是:把「看着能跑、实际埋雷」的写法提前拦住。
要不要在新代码里写 'use strict'?用 ES 模块或 class 就不用——它们自带严格模式;写传统 script(无 type="module")的老式页面则建议在 IIFE 或文件顶部开启。理解严格模式的价值更多在于读懂报错:当你在模块代码里看到 this 是 undefined、赋值静默失败变报错时,背后是它在起作用。
示例
// 演示严格模式差异:把代码包在带 'use strict' 的函数里
function strictDemo() {
'use strict';
try {
undeclaredVar = 1; // 未声明赋值 → 报错
} catch (e) {
console.log('未声明赋值:', e.constructor.name);
}
function standalone() {
return this;
}
console.log('独立调用 this:', standalone()); // undefined
try {
delete Object.prototype; // 删除不可配置属性 → 报错
} catch (e) {
console.log('删除受保护属性:', e.constructor.name);
}
}
strictDemo();
// 非严格模式的同一操作则静默通过
function sloppyDemo() {
silentVar = 42; // 悄悄创建全局变量
return typeof silentVar;
}
console.log('非严格模式:', sloppyDemo()); // 'number',不报错但留下全局污染
// class 与模块自动严格:class 里独立调用 this 是 undefined
class Demo {
static probe() {
const inner = function () {
return this;
};
return inner();
}
}
console.log('class 内部自动严格:', Demo.probe()); // undefined
常见坑
- 在模块代码顶部再写 'use strict':无害但多余,模块自带严格模式,看到别以为是必要代码。
- 踩了严格模式报错却找不到原因:模块/class 里「莫名其妙」的 ReferenceError(未声明赋值)、TypeError(改只读)多半是严格模式在帮你抓 bug,顺着报错修就好。
- 依赖非严格模式的 this 是 window:老代码里 fn() 内 this 指 window 的技巧在模块里全部失效,迁移代码时要改成显式参数。
- 混用脚本时的边界:严格模式按脚本/函数生效,拼接打包时别把严格和非严格代码无边界地揉在一起(现代打包器会处理,手写 拼接时要留意)。
小结
严格模式把静默错误变显式报错、收紧危险语法;ES 模块和 class 自动严格。下一节进入异步世界的第一站:回调函数。