3

仕様には次のように記載されています。

厳密モード コード内で識別子 eval または引数を 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/

この 2 番目のコード ブロックが構文エラーをスローする必要があることを理解しています。それはすべきですか?はいの場合、なぜそうしないのですか?

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 が strict モード コード (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
于 2011-12-11T22:51:33.450 に答える