eval()没有被移除,但它在严格模式下发生了一些变化。最大的改变是:在eval()语句中声明的变量以及函数不会在包含域中创建。例如:
(function() {
eval("var x = 10;");
// 非严格模式下,x为10
// 严格模式下,x没有声明,抛出一个错误
alert(x);
}());
任意由eval()创建的变量或函数仍呆在eval()里。然而,你可以通过从eval()中返回一个值的方式实现值的传递:
(function() {
var result = eval("var x = 10, y = 20; x + y");
// 严格模式与非严格模式下都能正常工作(得到30)
alert(result);
}());
不可改变引发的错误(Errors for immutables)
ECMAScript 5 同时引入了修改属性特征的能力,例如设置一个属性为只读或者冻结整个对象的结构(freezing an entire object’s structure)。在非严格模式下,试图修改一个不可变的属性时将悄无声息地失败。你可能在使用一些原生APIs的时候已经遇到这类问题。严格模式将保证无论你在何时试图使用一种不被允许的方式修改一个对象或对象的属性时抛出错误。
var person = {};
Object.defineProperty(person, "name" {
writable: false,
value: "Nicholas"
});
// 非严格模式下将悄无声息地失败,严格模式则抛出错误
person.name = "John";
这个例子中,name属性被设置为只读。在非严格模式下,对name的赋值将悄无声息地失败;而在严格模式下,一个错误将被抛出。
注:如果你在使用ECMAScript属性能力(the ECMAScript attribute capabilities),我强烈推荐你开启严格模式。如果你在改变对象的可变性(mutability of objects),你将遇到一堆错误,而它们在非严格模式下将被安静地带过。
该如何使用它?
在现代浏览器中很容易启用严格模式,只需添加下面一条语句:
"use strict";
虽然这看起来只是一个没有赋值给变量的字符串,但它确实地指示了Javascript引擎切换为严格模式(那些不支持严格模式的浏览器只是简单地读取了这个字符串然后继续像平常一样运行)。你可以在全局或函数中使用它。话虽这么说,你永远不应该在全局中使用它。全局地使用这条指示,意味着同个文件下的所有代码都在严格模式下运行。
// 别这么做
"use strict";
function doSomething() {
// 这将在严格模式下运行
}
function doSomethingElse() {
// 这也是
}
这看起来似乎不是个大问题,但在我们这个不同脚本堆积在一起的世界里(our world of aggressive script concatenation)将导致大麻烦。只要有一份脚本全局地包含这条指令,其它串联的脚本也将在严格模式下运行(可能引发一些你从没预想到的错误)。
因此,最好只在函数内使用严格模式,例如:
function doSomething() {
"use strict";
// 严格模式下运行
}
function doSomethingElse() {
// 非严格模式下运行
}
如果你想讲严格模式应用于多个函数,可以使用如下模式( immediately-invoked function expression (IIFE)):
(function() {
"use strict";
function doSomething() {
// this runs in strict mode
}