JavaScript 严格模式

在本教程中,你将学习如何在 JavaScript 中以严格模式执行代码。

什么是严格模式

严格模式是在 ECMAScript 的 (ES5) 引入的。它是一种语义更严格或受限制的 JavaScript 语言版本,会为那些以静默方式处理的错误产生错误。例如,在*非严格*模式下,如果初始化变量而不使用 var 关键字(例如 x = 5;) 声明它,则 JavaScript 解释器将假定你引用的是全局变量,如果不存在此变量,则它将自动创建一个变量。

此外,不推荐使用的功能也可能在严格模式下生成错误。因此,严格模式可以减少错误,提高应用程序的安全性和整体性能。

启用严格模式

要启用严格模式,你只需在脚本开头添加 use strict 字符串,如以下示例所示:

"use strict";

// All your code goes here
x = 5; // ReferenceError: x is not defined
console.log(x);

如果将 use strict 指令添加为 JavaScript 程序的第一行,则严格模式适用于整个脚本。但是,你也可以仅在函数内打开严格模式,如下所示:

x = 5;
console.log(x); // 5

function sayHello() {
    "use strict";
    str = "Hello World!"; // ReferenceError: str is not defined
    console.log(str);
}
sayHello();

注意:use strict 指令仅在脚本或函数的开头被识别。 use strict 除 Internet Explorer 9 及更低版本外外,所有现代浏览器都支持指令。此外,不支持 use strict 指令的浏览器会以静默方式忽略它并以非严格模式解析 JavaScript。

严格模式下的一般限制

严格模式会更改语法和运行时行为。在以下部分中,我们将介绍在严格模式下强制执行的一般限制:

不允许使用未声明的变量

如你所知,在严格模式下,必须声明所有变量。如果为不是声明变量的标识符赋值,则抛出 ReferenceError

"use strict";

function doSomething() {
    msg = "Hi, there!"; // ReferenceError: msg is not defined
    return msg;
}
console.log(doSomething());

不允许删除变量或函数

在严格模式下,如果尝试删除变量或函数,则会引发语法错误。然而,在非严格模式下,此类尝试以静默方式失败,并且 delete 表达式求值为 false

"use strict";

var person = {name: "Peter", age: 28};
delete person; // SyntaxError

同样,当你尝试在严格模式下删除函数时,你将收到语法错误:

"use strict";

function sum(a, b) {
    return a + b;
}
delete sum; // SyntaxError

不允许复制参数名称

在严格模式下,如果函数声明具有两个或多个具有相同名称的参数,则将引发语法错误。在非严格模式下,不会发生错误。

"use strict";

function square(a, a) { // SyntaxError
    return a * a;
}
console.log(square(2, 2));

eval 方法不能改变范围

在严格模式下,出于安全原因,传递给 eval() 的代码不能声明/修改变量或定义周围范围内的函数,因为它可以在非严格模式下。

"use strict";

eval("var x = 5;");
console.log(x); // ReferenceError: x is not defined

evalarguments 不能用作标识符

在严格模式下,名称 evalarguments 被视为关键字,因此它们不能用作变量名、函数名或函数参数名等。

"use strict";

var eval = 10; // SyntaxError
console.log(eval);

不允许使用 with 语句

在严格模式下,不允许使用 with 语句。该 with 语句将对象的属性和方法添加到当前范围。因此,嵌套在 with 语句中的语句可以直接调用对象的属性和方法而无需引用它。

"use strict";

// Without with statement
var radius1 = 5;
var area1 = Math.PI * radius1 * radius1;

// Using with statement
var radius2 = 5;
with(Math) { // SyntaxError
    var area2 = PI * radius2 * radius2;
} 

不允许写入只读属性

在严格模式下,将值分配给不可写属性,只获取属性或不存在的属性将引发错误。在非严格模式下,这些尝试会无声地失败。

"use strict";

var person = {name: "Peter", age: 28};

Object.defineProperty(person, "gender", {value: "male", writable: false});
person.gender = "female"; // TypeError

不允许向不可扩展的对象添加新属性

在严格模式下,尝试在不可扩展或不可存在的对象上创建新属性也会引发错误。但是在非严格模式下,这些尝试会无声地失败。

"use strict";

var person = {name: "Peter", age: 28};

console.log(Object.isExtensible(person)); // true
Object.freeze(person); // lock down the person object
console.log(Object.isExtensible(person)); // false
person.gender = "male"; // TypeError

不允许使用八进制数

在严格模式下,不允许八进制数字。但是,在非严格模式下,所有浏览器都支持它。但是,在 ES6 中,八进制数字由前缀 0o 和数字组成,即 0o10,0o377 等。

"use strict";

var x = 010; // SyntaxError
console.log(parseInt(x));

你可以在上面的示例中清楚地看到严格模式如何帮助你防止在编写 JavaScript 程序时经常被忽视的常见错误。

为未来的保留关键字被允许使用

正如你在前面章节中已经知道的那样,*保留字*不能用作 JavaScript 程序中的标识符(变量名,函数名和循环标签)。除此之外,严格模式还对使用那些为将来保留的关键字施加限制。

按照最新的 ECMAScript 6(或 ES6)标准,这些关键字是保留的关键字,当他们在严格模式代码被发现: awaitimplementsinterfacepackageprivateprotectedpublic ,和 static 。但是,为了获得最佳兼容性,应避免在程序中将保留关键字用作变量名或函数名。

提示: 保留字,这也是所谓的关键字,是属于 JavaScript 语言语法的一部分,例如特殊字词, varifforfunction 等。请参照 JS 保留关键字参考 为 JavaScript 中的保留字的完整列表。