2

JavaScript にはブロック スコープではなく関数スコープがあり、宣言はブロックから親関数の先頭に引き上げられると思いました。

ただし、次のコードは期待どおりに機能しません。

function one(a) {
    console.log("one called for " + a);

    if (a == 1) {
        function inner(b) {
            console.log("inner called for " + b);
        }

        inner(123);
    }

    inner(456);
}

one(1);
one(2);
one(3);

最初のone(1);呼び出しはエラーなしで正常に処理されますが、2 番目の呼び出しで実行が停止しone(2);ます。

この動作は直感的です。関数innerは の場合にのみ定義されa==1ます。

しかし、スコープ/ホイスト ルールとどのように整合性があるのでしょうか?

ifその定義は、効果がないはずのブロックの外で、そのスコープの一番上に引き上げられると思いました!

編集:ここに私が得ているエラーがあります:

エラーが表示されている Firefox コンソールのスクリーンショット

ブラウザは Firefox です。ここでフィドル。

4

2 に答える 2

2
if (…) {
    function …() {            
        …
    }
}

無効な ECMAScript です。関数宣言は、関数またはプログラム本体の最上位にある必要があり、ブロック内では、その動作は実装に依存します。Firefox はこの関数ステートメントを条件付きで実行しますが、他のブラウザーは通常の関数宣言のように巻き上げます。if ステートメントの外に移動するか、関数式を割り当てます。

于 2014-02-24T12:29:34.977 に答える
1

の宣言はinner、外側の関数の先頭に巻き上げられます。ただし、その値は の場合にのみ設定されますa == 1

outer()異なる値で呼び出された場合、 への呼び出しは に設定されたままでinner(456)失敗します。innerundefined

于 2014-02-24T10:31:04.673 に答える