规范指出:
It is a SyntaxError to use within strict mode code the identifiers eval or arguments as the Identifier of a FunctionDeclaration or FunctionExpression or as a formal parameter name (13.1). Attempting to dynamically define such a strict mode function using the Function constructor (15.3.2) will throw a SyntaxError exception.
来源: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/
据我了解,第二个代码块应该抛出一个语法错误。应该是?如果是,为什么不呢?
最佳答案
所以,我要在这里回答我自己的问题(因为我已经弄明白了)。
我最初的前提是两个代码块是等价的。这样
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 的语义中定义:
Pass in true as the Strict flag if the FunctionExpression is contained in strict code or if its FunctionBody is strict code.
因此,如果满足以下任一条件,函数对象将是严格的:
- 函数表达式包含在严格的代码中
- 函数表达式的函数体是严格的代码
例如,函数 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 步中定义(已在上面链接):
If body is strict mode code (see 10.1.1) then let strict be true, else let strict be false.
因此,new Function
调用是否包含在严格代码中是无关紧要的。要通过此模式创建严格函数,必须在函数体中显式定义严格性(这是提供给构造函数的最后一个参数。
new Function ( 'a, b', 'return a + b;' ); // not strict
new Function ( 'a, b', '"use strict"; return a + b;' ); // strict
关于javascript - 将 "eval"定义为 Function 构造函数调用的形式参数。这不应该在严格模式代码中引发语法错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8458980/