它是什么
给 JS 开个“较真模式”。一旦开启,JavaScript 会对一些原本“容忍/默默忽略”的危险写法直接抛错或改变行为,从而更早暴露 bug、更安全、更利于引擎优化。
为什么有意义
- 更早发现错误:很多隐性 bug 当场报错,缩短排查时间。
- 更安全:禁掉易被利用或难以理解的语法(如
with、arguments.callee)。 - 更一致:减少不同引擎下的歧义和历史包袱。
- 更好优化:明确语义后,JS 引擎更容易做性能优化。
怎么开启
- 在脚本或函数第一行写:
"use strict"; - ES6+ 模块与类默认就是严格模式;打包后的现代项目通常已经处于严格模式(多半不用手写这句)。
具体有什么变化(高频清单 + 例子)
- 禁止意外创建全局变量
"use strict";
function f() { x = 1 } // ReferenceError:x 未声明
(非严格下会悄悄变成 window.x)
- 普通函数里的
this不再自动指向全局
function f(){ return this }
f(); // 非严格: window/global;严格: undefined
- 参数名不能重复
function sum(a, a) {} // 严格: SyntaxError
eval变“隔离” (不再向外层注入变量)
"use strict";
eval("var x = 1;");
typeof x; // "undefined"
- 不能删除变量/函数/参数
"use strict";
var x = 1;
delete x; // SyntaxError
- 写入只读属性会抛错(非严格下静默失败)
"use strict";
const obj = {};
Object.defineProperty(obj, "id", { value: 1, writable: false });
obj.id = 2; // TypeError
- 禁用
with
"use strict";
with (obj) {} // SyntaxError
- 八进制字面量与转义受限
"use strict";
var n = 010; // SyntaxError(非严格下表示八进制 8)
arguments行为更“干净”
- 不再和形参联动(改
arguments[0]不会改到形参)。 - 禁用
arguments.callee/arguments.caller(TypeError)。 - 不能给
eval/arguments赋值或作为变量名。
- 保留字更严格
像public、static(以及未来关键字)在严格模式下不可作为变量名。
什么时候我“已经在严格模式”?
- 你用 ES modules (
import/export) 或 class:默认严格。 - 现代打包工具(Webpack、Vite、Rollup)产物通常已严格。
- 旧式 IIFE/脚本直连时,若没模块化,才可能需要手写
"use strict"。
实战建议
- 新项目/模块化项目:基本天然严格,无需额外处理。
- 维护旧代码:可以按“文件或函数”为单位逐步加
"use strict",配合 eslint,把上面这些典型坑扫一遍。 - 库作者:保持严格模式有助于用户环境一致性与可优化性。