定义“评估”作为 Function 构造函数调用的形式参数。这不应该在严格模式代码中引发语法错误吗?

发布于 2024-12-20 14:00:40 字数 887 浏览 2 评论 0原文

规范指出:

在严格模式代码中使用标识符是一个语法错误 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/

据我了解,第二个代码块应该抛出语法错误。应该吗?如果是的话,为什么不呢?

The specification states:

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.

Source: http://es5.github.com/C.html#C (last bullet)

Therefore, this throws a syntax error (in Firefox, Chrome, and Opera):

(function () {
    'use strict';

    var f = function ( eval ) {};
})();

Live demo: http://jsfiddle.net/v8Ff4/

However, this doesn't throw a syntax error:

(function () {
    'use strict';

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

Live demo: http://jsfiddle.net/v8Ff4/1/

It is my understanding that this second code-block should throw a syntax error. Should it? And if yes, why doesn't it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

静谧 2024-12-27 14:00:40

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

我最初的前提是两个代码块是等效的。因此这

var f = function ( eval ) {};

相当于

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

但这不是真的。存在差异。 第 13.2 章创建函数对象。另一方面,从 new Function 构造函数调用创建函数对象在 第 15.3.2.1 章新函数 (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!';
    }    
})();

函数构造函数调用

通过函数构造函数调用创建的函数对象的严格性在第 15.3.2.1 章算法的第 9 步中定义(已在上面链接):

如果 body 是严格模式代码(参见 10.1.1),则让 strict 为 true,否则让 strict 为 false。

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

new Function ( 'a, b', 'return a + b;' ); // not strict
new Function ( 'a, b', '"use strict"; return a + b;' ); // strict

So, I'm going to answer my own question here (since I've figured it out).

My initial premise was that both code blocks are equivalent. So that this

var f = function ( eval ) {};

is equivalent to

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

This is however not true. There are differences. The creation of a function object from a function declaration / expression notation is defined in Chapter 13.2 Creating Function Objects. On the other hand, the creation of a function object from a new Function constructor invocation is defined in Chapter 15.3.2.1 new Function (p1, p2, … , pn, body). So there are different algorithms at work here.

The specific part which is relevant to this question is the part which defines the strictness of the created function object.

Function expressions

The strictness of a function object created via a function expression is defined in the semantics of the production FunctionExpression at the beginning of chapter 13:

Pass in true as the Strict flag if the FunctionExpression is contained
in strict code or if its FunctionBody is strict code.

So the function object will be strict if either one of these conditions is met:

  • the function expression is contained in strict code
  • the function body of the function expression is strict code

so for instance, the function f is strict in both examples below.

Example 1:

(function () {    
    var f = function () {
        'use strict';
        return 'I am strict!';
    }    
})();

Example 2:

(function () {
    'use strict';    
    var f = function () {
        return 'I am strict!';
    }    
})();

Function constructor invocation

The strictness of a function object created via a Function constructor invocation is defined in step 9 of the algorithm from Chapter 15.3.2.1 (already linked above):

If body is strict mode code (see 10.1.1) then let strict be true, else let strict be false.

So, whether or not the new Function invocation is contained in strict code is irrelevant. To create a strict function via this pattern, one has to explicitly define the strictness in the function body (which is the last argument supplied to the constructor.

new Function ( 'a, b', 'return a + b;' ); // not strict
new Function ( 'a, b', '"use strict"; return a + b;' ); // strict
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文