为什么理解严格模式是理解 JavaScript 的关键
严格模式(Strict Mode)是 ES5 引入的一个重要特性。它不仅仅是一组限制——它修复了 JavaScript 早期设计中的很多缺陷,让代码行为更可预测。
理解严格模式,有助于理解 JavaScript 的历史遗留问题,以及为什么 ES Module 默认处于严格模式。
一、开启严格模式
1.1 开启方式
// 方式一:脚本顶层
"use strict";
function test() { }
// 方式二:函数内
function test() {
"use strict";
}
// 方式三:ES Module 自动开启
// module.js — 默认处于严格模式
export default function() { }
1.2 在类中的表现
// ES6 class 自动处于严格模式
class StrictClass {
method() {
// 这里自动是严格模式
}
}
二、严格模式禁止的行为
2.1 禁止未声明变量
"use strict";
x = 10; // ReferenceError: x is not defined
// 正确做法
let x = 10;
2.2 禁止 with 语句
"use strict";
const obj = { x: 1, y: 2 };
with (obj) { // SyntaxError
console.log(x + y);
}
2.3 禁止删除不可删除的属性
"use strict";
delete Object.prototype; // TypeError
// 正常删除
const obj = { x: 1 };
delete obj.x; // OK
2.4 禁止函数参数名重复
"use strict";
function f(a, a) { // SyntaxError
return a + a;
}
2.5 禁止八进制字面量
"use strict";
const n = 010; // SyntaxError
const hex = 0x10; // OK (十六进制)
const binary = 0b10; // OK (二进制)
三、严格模式对 this 的影响
3.1 全局函数中的 this
function foo() {
console.log(this);
}
foo(); // 非严格:window,严格:undefined
3.2 构造函数中的 this
function Person(name) {
this.name = name;
}
const p = new Person('Alice'); // 两种模式都正常工作
// 直接调用构造函数(不使用 new)
function Person2(name) {
"use strict";
this.name = name;
}
Person2('Bob'); // 严格模式:this 是 undefined,非严格:this 是全局对象
四、严格模式对 arguments 的影响
4.1 arguments 的原始行为
// 非严格模式:arguments 跟踪参数变化
function trackArgs(a) {
arguments[0] = 100;
console.log(a); // 100
}
trackArgs(1); // 输出 100
// 严格模式:arguments 不再追踪参数变化
"use strict";
function strictArgs(a) {
arguments[0] = 100;
console.log(a); // 1
}
strictArgs(1); // 输出 1
4.2 arguments.callee
"use strict";
// arguments.callee 在严格模式中被禁用
const factorial = function(n) {
if (n <= 1) return 1;
return n * arguments.callee(n - 1); // TypeError
};
// 应该使用命名函数表达式
const factorial = function fact(n) {
if (n <= 1) return 1;
return n * fact(n - 1);
};
五、严格模式在现代 JavaScript 中的地位
5.1 ES Module 默认严格模式
ES Module 代码默认处于严格模式,不需要显式 "use strict":
// module.js
export const PI = 3.14159;
// 无需 "use strict",已经是严格模式
5.2 严格模式的优势
- 代码更安全:提前捕获错误,而不是默默失败
- 引擎优化:严格模式更容易优化
- 未来兼容:一些新特性只在严格模式可用