JavaScript 严格模式

深入解析 JavaScript 严格模式的作用:禁止 with、禁止未声明变量、arguments 原始行为、this 指向,以及 ES Module 为什么默认严格模式。

为什么理解严格模式是理解 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 严格模式的优势

  1. 代码更安全:提前捕获错误,而不是默默失败
  2. 引擎优化:严格模式更容易优化
  3. 未来兼容:一些新特性只在严格模式可用

六、延展阅读