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
eval
和 arguments
不能用作标识符
在严格模式下,名称 eval
和 arguments
被视为关键字,因此它们不能用作变量名、函数名或函数参数名等。
"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)标准,这些关键字是保留的关键字,当他们在严格模式代码被发现: await
, implements
, interface
, package
, private
, protected
, public
,和 static
。但是,为了获得最佳兼容性,应避免在程序中将保留关键字用作变量名或函数名。
提示: 保留字,这也是所谓的关键字,是属于 JavaScript 语言语法的一部分,例如特殊字词, var
, if
, for
, function
等。请参照 JS 保留关键字参考 为 JavaScript 中的保留字的完整列表。