3

该规范指出:

在严格模式代码中使用标识符 eval 或 arguments 作为 FunctionDeclaration 或 FunctionExpression 的标识符或形式参数名称 (13.1) 是 SyntaxError。尝试使用 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/

据我了解,第二个代码块应该引发语法错误。应该是?如果是,为什么不呢?

4

1 回答 1

2

所以,我将在这里回答我自己的问题(因为我已经弄清楚了)。

我最初的前提是两个代码块是等价的。所以这

var f = function ( eval ) {};

相当于

var f = new Function( 'eval', '' );

然而,这不是真的。有区别。从函数声明/表达式符号创建函数对象在第 13.2 章创建函数对象中定义。另一方面,从new Function构造函数调用创建函数对象在第 15.3.2.1 章 new Function (p1, p2, ... , pn, body)中定义。所以这里有不同的算法在起作用。

与这个问题相关的具体部分是定义创建的函数对象的严格性的部分。

函数表达式

通过函数表达式创建的函数对象的严格性在第 13 章开头的产生式FunctionExpression的语义中定义:

如果 FunctionExpression 包含在严格代码中或其 FunctionBody 是严格代码,则传入 true 作为 Strict 标志。

因此,如果满足以下任一条件,则函数对象将是严格的:

  • 函数表达式包含在严格的代码中
  • 函数表达式的函数体是严格代码

例如,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),那么让 strict 为真,否则让 strict 为假。

因此,new Function调用是否包含在严格的代码中是无关紧要的。要通过这种模式创建一个严格的函数,必须在函数体中显式定义严格性(这是提供给构造函数的最后一个参数。

new Function ( 'a, b', 'return a + b;' ); // not strict
new Function ( 'a, b', '"use strict"; return a + b;' ); // strict
于 2011-12-11T22:51:33.450 回答