6

ブロックスコープで関数を定義するときに問題が発生しました。私はMerry Christmas!を警告するためにこのプログラムを期待関数宣言または関数式

try { 
    greet(); 

    function greet() { 
     alert("Merry Christmas!"); 
    } 
} catch (error) { 
    alert(error); 
} 

:次のプログラムを考えてみましょう。

オペラとChromeで
ReferenceError: greet is not defined 

私はそれが期待どおりに挨拶を警告:しかし、Firefoxで私に次ReferenceErrorを与えています。

明らかにFirefoxはブロックスコープ内の機能をFunctionExpressionとして扱い、OperaとChromeはそれをFunctionDeclarationとして扱います。

私の質問はなぜFirefoxの動作が違うのですか?どの実装がより論理的ですか?どの規格が規格に準拠していますか?

JavaScript内の宣言が呼び出されているので、同じ関数が同じスコープ内の2つ以上の異なるブロックで宣言されていると、名前の競合が発生することがあります。あなたはこのような何かを行うことができるように

は、しかし、機能にそれが宣言されていますたびに再宣言するより論理的ではないでしょう。

greet(); // Merry Christmas! 

function greet() { 
    alert("Merry Christmas!"); 
} 

greet(); // Happy New Year! 

function greet() { 
    alert("Happy New Year!"); 
} 

私は、これはブロックの解決に加えて、非常に有用であろうと思います上記のスコープの問題。

+0

"関数は宣言される度に関数を再宣言して、このようなことをすることができます" - それらは*再参照され、一度だけ宣言が発生し、それが吊り上げられます。あなたは前の段落で確認していない、あなたは吊り上げを理解していますか? – katspaugh

+2

はい私はJavaScriptで巻き上げを理解しています。いいえ、私の文は完全にはっきりしています。私が言っていることは、インタプリタが(関数宣言が宣言されるたびに)関数宣言が出現するたびに、それが同じスコープ内の関数の前の宣言(関数の宣言)までしか呼び出されないことです。この機能はJavaScriptには存在しないため、現在のJavaScript標準を引用して無効にすることはできません。それは単なる提案です。 JavaScriptで同じ関数の複数の宣言を実装するための提案。希望はあなたに明快さをもたらします。メリークリスマス@ katspaugh –

+0

ああ、そうだよ。ありがとう、それはESボード上の誰にも起こらなかった。メリークリスマス、アディット! :) – katspaugh

答えて

5

実際には、ブロックスコープ内の関数宣言は、ではなく、が標準化されており、動作は実装に依存しています。異なる実装は、異なって応答します。 if文の中で関数を宣言しようとすると、同じ奇妙なことが起こります。

ES5仕様では、実装者がブロック内の関数宣言を警告またはエラーとしてマークすることを推奨しています。

+0

ブロックスコープ内に関数を宣言しないでください。おそらくそれは良いプログラミングの練習です。 javascriptの横にある –

+0

はasync langです。 – Omiga

+0

@ Janim007と呼ぶ前に関数を定義する必要があります。この問題の要点は、JavaScriptでは定義前に関数をトポロジカルに呼び出すことができることです。 – katspaugh

関連する問題