9

JavaScript 関数では、ネストされた関数を関数式として定義する必要がありますか、それとも関数本体で関数宣言を使用できますか? たとえば、このようなものは準拠していますか?

function a() {
    function b() {
        function c() {
            window.alert(3);
        }
        window.alert(2);
    }
    window.alert(1);
}

それとも、このようなことをしなければなりませんか?

function a() {
    var a = function () {
        var c = function () {
            window.alert(3);
        }
        window.alert(2);
    }
    window.alert(1);
}

ECMA-262 は次のように述べています。

広く使用されている ECMAScript の実装のいくつかは、Statement としての FunctionDeclaration の使用をサポートすることが知られています。ただし、そのような FunctionDeclarations に適用されるセマンティクスの実装には、重大で相容れないバリエーションがあります。これらの相容れない違いのため、FunctionDeclaration を Statement として使用すると、実装間で確実に移植できないコードが生成されます。ECMAScript の実装では、この FunctionDeclaration の使用を禁止するか、そのような使用が発生した場合に警告を発行することをお勧めします。ECMAScript の将来の版では、Statement コンテキストで関数を宣言するための代替の移植可能な手段が定義される可能性があります。

これは、関数本体の関数宣言が技術的に正しくないということですか、それとも完全に間違っているのでしょうか? 人々がボディをブロックと呼んでいると聞いたことがありますが、これは標準によれば 1 つまたは複数のステートメントですが、よくわかりません。

4

1 に答える 1

5

FunctionDeclaration は確かに関数本体で許可されており、私が認識しているバグはありません。

ES5 のプロダクション ルールを見れば明らかです。

FunctionBody
  SourceElements (opt)

SourceElements
  SourceElement
  SourceElements SourceElement

SourceElement
  Statement
  FunctionDeclaration

つまり、関数本体にはソース要素が含まれ、ソース要素は Statement または FunctionDeclaration のいずれかです。したがって、FunctionDeclaration は関数本体の一部にすることができます。

「...ECMAScriptの実装...ステートメントとしてのFunctionDeclarationの使用をサポートすることが知られている」について言及した句は、FunctionDeclarationをステートメントとして使用することを指しますが、関数本体では直接使用しません。次のような場合を指しています。

if (...) {
  function f () {}
}

これは標準化されていない動作です。これらの関数ステートメントの詳細を確認してください。

于 2013-02-15T13:25:14.100 に答える