中括弧の配置によって結果が異なるのはなぜですか?


119

この記事から抜粋した以下のコードスニペットでは、中括弧の配置が1回だけ変更されているため、異なる結果が生成されるのはなぜですか。

開始中括弧{が新しい行にある場合、test()が返さundefinedれ、アラートに「いいえ-壊れました:未定義」が表示されます。

function test()
{
  return
  { /* <--- curly brace on new line */
    javascript: "fantastic"
  };
}

var r = test();
try {
  alert(r.javascript); // does this work...?
} catch (e) {
  alert('no - it broke: ' + typeof r);
}

ブレースは、同じ行にある場合returntest()オブジェクトを返し、「素晴らしい」警告されます。

function test()
{
  return { /* <---- curly brace on same line */
    javascript: "fantastic"
  };
}

var r = test();
try {
  alert(r.javascript); // does this work...?
} catch (e) {
  alert('no - it broke: ' + typeof r);
}


後の半挿入のセマンティクスreturnは他の場所とは少し異なり、改行はその場所で「中流」よりも「より多く」を意味します。
dandavis 2015年

回答:


165

これがJavaScriptの落とし穴の1つです。セミコロンの自動挿入です。セミコロンで終わらないがステートメントの終わりである可能性のある行は自動的に終了するため、最初の例は次のようになります。

function test()
{
  return; // <- notice the inserted semicolon
  { 
    javascript: "fantastic"
  };
}

セミコロンの挿入について言及しているDouglas CrockfordのJSスタイルガイドも参照してください。

2番目の例では、プロパティjavascriptとその値が"fantastic"である(中かっこで構築された)オブジェクトを返します。これは、実質的に次のようになります。

function test() {
    var myObject = new Object();
    myObject.javascript = "fantastic";
    return myObject;
}

5
豆知識:一部のエンジンでは、自動挿入されたセミコロンをコメントアウトできます
Christopher Tarquini

1
@クリス:何?どれ?これはどこか探検されていますか?
Sean McMillan

1
@SeanMcMillan確かにそれに関する記事を読みましたが、クイック検索からそれらを見つけることができないようです。以前のバージョンのchromeに隠されたセミコロンを置いてコメントアウトするreturn /*と、覚えています*/{ 。それがまだ当てはまるかどうかわからない
クリストファー

2
これらの癖のため、私は10年前に自分に約束しました。ウェブから離れてください!インターウェブが衰退することを祈りました...残念ながら、それは計画通りにはいきませんでした、そして今、私はこれらの問題にも苦労する必要があります。Karmaはab * tchです:)
Jowen

1
JavaScriptでセミコロンに熱心に反対する人を見てきましたが、セミコロンを入れないことで節約できる余分な時間をどうすればいいのかといつも思っていました。
イマンモハマディ2018

9

JavaScriptはステートメントの最後にセミコロンを必要としませんが、欠点はセミコロンの場所を推測する必要があることです。ほとんどの場合、これは問題ではありませんが、意図しないセミコロンが作成される場合があります。

これに関する私のブログ投稿の例(JavaScript-ほとんど行ベースではない):

このようにコードをフォーマットすると:

function getAnswer() {
   var answer = 42;
   return
      answer;
}

次に、次のように解釈されます。

function getAnswer() {
  var answer = 42;
  return;
  answer;
}

returnステートメントはパラメーターのない形式を取り、引数は独自のステートメントになります。

コードでも同じことが起こります。関数は次のように解釈されます。

function test()
{
  return;
  {
    javascript : "fantastic"
  };
}

3

私は個人的には、読みやすさの点でオールマンスタイル(vs K&Rスタイル)を好みます。

の代わりに…

function test() {
  return {
    javascript : "fantastic"
  };
}

好き…

function test() 
{
  var obj =
  {
    javascript : "fantastic"
  };

  return obj;
}

しかし、これは回避策です。私はそれと一緒に暮らすことができます。


3
主流から逸脱する個人的な好みは避けるべきだと思います。大多数の選択に従う必要があります。これにより一貫性が向上し、読みやすさが向上します
Jowen

1
彼のコードはK&Rよりも読みやすいと思います。「可読」を意味する場合、かなり主観的
ブランマル

私もAllmanを好みますが、ASIのため、オブジェクトを返す必要がある場合は、セミとリターンと同じ行に残します。「var x =」行を1つ追加するよりも、これを好みます...
Mik

1

それは、javascriptが最もよく「;」を置くためです。各行の終わりにあるので、基本的には、同じ行に{を返すと、JavaScriptエンジンはさらに何かがあることを確認し、新しい行に「;」を入れるのを忘れたと考えて、それを挿入します。


1
Cichy、Darin、Ivoの回答が反対票だった理由がわかりませんか?
BoltClock

1

ここで中括弧は、新しいオブジェクトの作成を示します。したがって、コードは次と同等です。

function test() {
  var a = { javascript : "fantastic" };
  return a;
}

これは機能しますが、あなたが書く場合:

function test() {
  var a = { javascript : "fantastic" };
  return; // ; is automatically inserted 
      a;
}

それはもはや機能しません。


0

問題は、実際に上記のセミコロン注入です。私はこの件に関して良いブログ投稿を読んだだけです。この問題と、JavaScriptの詳細について説明しています。また、いくつかの優れたリファレンスも含まれています。ここで読めます


はい、私はそれも読んでいます。読んでいるときは、ここでjsの首謀者によるより良い説明を求めます。
JustLearn
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.