JavaScriptの質問です。

以下のコードを実行させると、
 Firefoxでは「true」(2つ目はエラー)
 Chromeでは「false」「true」
とアラートが出るのですが、これはどのような仕様の違いから生まれているのでしょうか?
参考になるページなどがあれば教えてください。
 
 
 
if(1){
  function a(){
    return true
  }
}else{
  function a(){
    return false
  }
}
while(0){
  function b(){
    return true
  }
}
alert(a());
alert(b());

回答の条件
  • 1人1回まで
  • 登録:2011/10/14 19:22:55
  • 終了:2011/10/15 10:18:40

ベストアンサー

id:Cherenkov No.1

Cherenkov回答回数1503ベストアンサー獲得回数4932011/10/15 03:20:22

ポイント300pt

注: SpiderMonkey 以外の JavaScript エンジンの中には、名前の付いた関数式を全て関数宣言と間違ってみなすものがあります。これによって常に偽となる条件式の中にあっても zero が定義されてしまいます。

関数 - MDN

IE9,Chrome14,Safari5,Opera11 vs Firefox7




<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<p><a href="http://q.hatena.ne.jp/1318587775">http://q.hatena.ne.jp/1318587775</a></p>
<script>
if(1){
  a = function a(){
    return 'a1'
  }
}else{
  a = function a(){
    return 'a2'
  }
}
while(0){
  b = function b(){
    return 'b'
  }
}
alert(a());
alert(b());
</script>
</body>
</html>
id:Lhankor_Mhy

おお、なるほどよく分かりました。

「ソース要素」とかなんか怪しげな定義だな、と思いましたが、ECMAscript仕様日本語訳見てきましたが、そのとおりなんですね。たしかに関数定義のためにブロックの中を処理してない。

ECMAscript準拠という意味では、Firefoxの動作が正しくて他のブラウザが間違ってるんですね。

 

とても勉強になりました、ありがとうございます。

2011/10/15 10:18:06
  • id:teramako
    ECMAScript的な観点では仕様違反です。if文やwhile文の中に関数宣言を入れることは本来はできません。その意味ではどのブラウザも構文エラーにならないため、仕様違反をしていると言えます(まぁこの仕様違反は「わざと」でしょうけども)。なので、各ベンダーで独自実装となっており挙動はそのJSエンジン依存となってしまっているのが現状です。

    詳細はこちらを参照ください。 http://nanto.asablo.jp/blog/2005/12/10/172622

    ただ、これはECMAScript 3rd, 5thまでの話。現在 5h まで出てますが、次の ECMASCript 6th の仕様(Draft)を見る限りブロック中に関数宣言が可能になっています。6thを各ベンダーが実装すれば、挙動は安定すると思われます。
  • id:Lhankor_Mhy
    おお、なるほど。
    私も「FunctionExpression とみなされるのでは」と思って読んでました。
    ということは、
    (function a(){})
    は正しい書き方ということになるわけなんですね。意味はないけど。
  • id:think49
    > ということは、
    > (function a(){})
    > は正しい書き方ということになるわけなんですね。意味はないけど。

    名前があれば再帰的に関数自身を参照できます。

    ---
    /**
    * 常に 0 の近似値を返す関数
    */
    (function a (i) {
    return --i ? a(i) : i;
    })(5);
    ---

    arguments.callee を使えば名前は不要と思われるかもしれませんが、Strict Mode では使えませんので価値はあると思います。
    ただし、IE8- はスコープ漏れするのでやや使いにくい感は残りますね。
    http://d.hatena.ne.jp/think49/20110521/1305959222

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません