规范声明:
在严格模式代码中使用标识符是一个SyntaxError eval或arguments作为FunctionDeclaration或的标识符 FunctionExpression或作为形式参数名称(13.1)。试图 使用Function动态定义这样的严格模式函数 构造函数(15.3.2)将抛出一个SyntaxError异常。
来源:http://es5.github.com/C.html#C(最后一颗子弹)
因此,这会引发语法错误(在Firefox,Chrome和Opera中):
(function () {
'use strict';
var f = function ( eval ) {};
})();
现场演示: http://jsfiddle.net/v8Ff4/
但是,这不会引发语法错误:
(function () {
'use strict';
var f = new Function( 'eval', '' );
})();
现场演示: http://jsfiddle.net/v8Ff4/1/
据我所知,第二个代码块应该抛出语法错误。应该是?如果是的话,为什么不呢?
答案 0 :(得分:2)
所以,我将在这里回答我自己的问题(因为我已经弄明白了)。
我最初的前提是两个代码块都是等价的。这就是这个
var f = function ( eval ) {};
相当于
var f = new Function( 'eval', '' );
但事实并非如此。有区别。从函数声明/表达式表示法创建函数对象在Chapter 13.2 Creating Function Objects中定义。另一方面,new Function
构造函数调用中创建的函数对象在Chapter 15.3.2.1 new Function (p1, p2, … , pn, body)中定义。所以这里有不同的算法。
与此问题相关的特定部分是定义所创建的函数对象的严格性的部分。
功能表达
通过函数表达式创建的函数对象的严格性在第13章开头的生产 FunctionExpression 的语义中定义:
如果包含FunctionExpression,则将true作为Strict标志传入 在严格的代码中或者如果它的FunctionBody是严格的代码。
因此,如果满足以下任一条件,函数对象将是严格的:
因此,例如,函数f
在以下两个示例中都是严格的。
示例1:
(function () {
var f = function () {
'use strict';
return 'I am strict!';
}
})();
示例2:
(function () {
'use strict';
var f = function () {
return 'I am strict!';
}
})();
函数构造函数调用
通过Function构造函数调用创建的函数对象的严格性在第15.3.2.1节(上面已经链接)的算法的步骤9中定义:
如果body是严格模式代码(见10.1.1),那么let strict为true,否则let strict为false。
因此,new Function
调用是否包含在严格的代码中无关。要通过此模式创建严格函数,必须在函数体中明确定义严格性(这是提供给构造函数的最后一个参数。
new Function ( 'a, b', 'return a + b;' ); // not strict
new Function ( 'a, b', '"use strict"; return a + b;' ); // strict