一、 函数参数
ES6 增加了剩余操作符、解构操作符和默认参数,为函数组织、结构和定义参数提供了强大的支持。
ECMAScript 7 增加了一条限制,要求使用任何上述先进参数特性的函数内部都不能使用严格模式,否则会抛出错误。不过,全局严格模式还是允许的。
// 可以
function foo(a, b, c) {
"use strict";
}
// 不可以
function bar(a, b, c='d') {
"use strict";
}
// 不可以
function baz({a, b, c}) {
"use strict";
}
// 不可以
function qux(a, b, ...c) {
"use strict";
}
ES6 增加的这些新特性期待参数与函数体在相同模式下进行解析。如果允许编译指示"use strict"出现在函数体内,JavaScript 解析器就需要在解析函数参数之前先检查函数体内是否存在这个编译指示,而这会带来很多问题。为此,ES7 规范增加了这个约定,目的是让解析器在解析函数之前就确切知道该使用什么模式
二、eval()
eval()函数在严格模式下也有变化。最大的变化是 eval()不会再在包含上下文中创建变量或函
数。例如:
// 使用 eval()创建变量
// 非严格模式:警告框显示 10
// 严格模式:调用 alert(x)时抛出 ReferenceError
function doSomething(){
eval("let x = 10");
alert(x);
}
以上代码在非严格模式下运行时,会在 doSomething()函数内部创建局部变量 x,然后 alert()
会显示这个变量的值。在严格模式下,调用 eval()不会在 doSomething()中创建变量 x,由于 x 没有
声明,alert()会抛出 ReferenceError。
变量和函数可以在 eval()中声明,但它们会位于代码执行期间的一个特殊的作用域里,代码执行
完毕就会销毁。因此,以下代码就不会出错:
"use strict";
let result = eval("let x = 10, y = 11; x + y");
alert(result); // 21
这里在 eval()中声明了变量 x 和 y,将它们相加后返回得到的结果。变量 result 会包含 x 和 y
相加的结果 21,虽然 x 和 y 在调用 alert()时已经不存在了,但不影响结果的显示。
三、eval 与 arguments
严格模式明确不允许使用 eval 和 arguments 作为标识符和操作它们的值。例如:
// 将 eval 和 arguments 重新定义为变量
// 非严格模式:可以,没有错误
// 严格模式:抛出 SyntaxError
let eval = 10;
let arguments = "Hello world!";
在非严格模式下,可以重写 eval 和 arguments。在严格模式下,这样会导致语法错误。不能用它
们作为标识符,这意味着下面这些情况都会抛出语法错误:
使用 let 声明;
赋予其他值;
修改其包含的值,如使用++;
用作函数名;
用作函数参数名;
在 try/catch 语句中用作异常名称