15

ご存じかもしれませんが、ECMAscript は賢くしようとし、セミコロンを明示的に記述していない場合は自動的にセミコロンを挿入します。簡単な例

function foo() {
    var bar = 5

    return bar
}

引き続き期待どおりに動作します。ただし、これに頼る場合は注意点があります。その関数をそのように書き直すと

function foo() {
    var bar = 5

    return
    {
        bar: bar
    }
}

..その関数はundefined、インタープリターがステートメントの直後にそのセミコロンを挿入するため、返されるようになりましたreturn(これが、常にステートメントと同じ行に中括弧を配置する必要がある理由です)。

ただし、これらすべてを知っていると、次のようなステートメントがブラウザーやバージョン間でどれほど安全か疑問に思っていますreturn

function foo() {
    var a = true,
        b = true,
        c = false;

    return a 
            && b
            && c;
}

return statement本番環境で同様のことを書きました。ECMAscript がセミコロンの挿入についてあまり賢くないという「問題」を知っていたからといって、そのコードが 100% 機能するかどうか疑問に思っています。FF/Chrome/IE (最新バージョン) での最初のテストでは、これはまったく問題ないように見えますが、本当にそうなのでしょうか?

その行にステートメント以外の何かがある場合、自動セミコロン挿入は「ウェイクアップ」しますか? returnこれについて実装レベルの詳細を提供できる人はいますか?

4

3 に答える 3

13

JavaScript インタープリター/コンパイラーは非常にスマートで、後で有効な Javascript がある場合にのみ自動セミコロンを挿入します。

&& bそのままでは有効な式ではないため、コードは機能します。そのため、return a結果の後にセミコロンが挿入されません。

return a && b && c;

でも:

return (undefined);//implicitely inserted
{
    ....
}

完全に有効なので、セミコロンが挿入されます。

完全を期すために、仕様への参照:自動セミコロン挿入。例は一読の価値があります。

于 2012-10-05T12:31:08.903 に答える
2

ブラウザ/実装固有ではありませんがSection 7.9 Automatic Semicolon InsertionECMAScript 言語仕様は一読の価値があります。

7.9 自動セミコロン挿入

特定の ECMAScript ステートメント (empty ステートメント、variable ステートメント、expression ステートメント、do-while ステートメント、continue ステートメント、break ステートメント、return ステートメント、および throw ステートメント) は、セミコロンで終了する必要があります。このようなセミコロンは、常にソース テキストに明示的に表示されます。ただし、便宜上、このようなセミコロンは、特定の状況ではソース テキストから省略される場合があります。これらの状況は、これらの状況でセミコロンがソース コード トークン ストリームに自動的に挿入されると説明されています。

7.9.1 セミコロンの自動挿入の規則 セミコロンの挿入には、次の 3 つの基本的な規則があります。

  1. プログラムが左から右に解析されるときに、文法のどの生成でも許可されていないトークン (問題のトークンと呼ばれる) が検出されると、次の 1 つ以上の場合、問題のトークンの前にセミコロンが自動的に挿入されます。条件は真です:

    • 問題のあるトークンは、少なくとも 1 つの LineTerminator によって前のトークンから分離されています。
    • 問題のあるトークンは } です。
  2. プログラムが左から右に解析されるときに、トークンの入力ストリームの終わりが検出され、パーサーが入力トークン ストリームを単一の完全な ECMAScript プログラムとして解析できない場合、セミコロンが末尾に自動的に挿入されます。入力ストリーム。

  3. プログラムが左から右に解析されるときに、文法の一部の生成によって許可されるトークンが検出されたが、生成が制限された生成であり、トークンが注釈の直後の終端または非終端の最初のトークンになる場合?[ここに LineTerminator はありません]? 制限されたプロダクション内 (したがって、そのようなトークンは制限されたトークンと呼ばれます) であり、制限されたトークンが少なくとも 1 つの LineTerminator によって前のトークンから分離されている場合、制限されたトークンの前にセミコロンが自動的に挿入されます。ただし、前述のルールには追加のオーバーライド条件があります。セミコロンが空のステートメントとして解析される場合、またはそのセミコロンが for ステートメントのヘッダーにある 2 つのセミコロンの 1 つになる場合、セミコロンは自動的に挿入されません ( 12.6.3)。注 以下は、文法で制限されている唯一のプロダクションです: PostfixExpression : LeftHandSideExpression [ここに LineTerminator なし] ++ LeftHandSideExpression [ここに LineTerminator なし] -- ContinueStatement : continue [ここに LineTerminator なし] Identifier ; BreakStatement : break [ここに LineTerminator はありません] Identifier ; ReturnStatement : return [ここに LineTerminator はありません] Expression ; ThrowStatement : throw [ここに LineTerminator はありません] Expression ; これらの制限された生成の実際の効果は次のとおりです: パーサーが後置演算子として処理する場所で ++ または -- トークンが検出され、前のトークンと ++ または -- トークンの間に少なくとも 1 つの LineTerminator が発生した場合。の場合、++ または -- トークンの前にセミコロンが自動的に挿入されます。コンティニュー、ブレイク、リターンのとき、または throw トークンが検出され、次のトークンの前に LineTerminator が検出された場合、continue、break、return、または throw トークンの後にセミコロンが自動的に挿入されます。その結果、ECMAScript プログラマーへの実際的なアドバイスは次のようになります。後置 ++ または -- 演算子は、そのオペランドと同じ行に表示する必要があります。return または throw ステートメントの Expression は、return または throw トークンと同じ行から開始する必要があります。break または continue ステートメントの識別子は、break または continue トークンと同じ行にある必要があります。return または throw ステートメントの Expression は、return または throw トークンと同じ行から開始する必要があります。break または continue ステートメントの識別子は、break または continue トークンと同じ行にある必要があります。return または throw ステートメントの Expression は、return または throw トークンと同じ行から開始する必要があります。break または continue ステートメントの識別子は、break または continue トークンと同じ行にある必要があります。

7.9.2 自動セミコロン挿入の例

起源

{ 1 2 } 3

自動セミコロン挿入規則を使用しても、ECMAScript 文法では有効な文ではありません。それに対し、ソースは

{ 1
2 } 3

も有効な ECMAScript 文ではありませんが、自動セミコロン挿入によって次のように変換されます。

{ 1
;2 ;} 3;

これは有効な ECMAScript 文です。起源

for (a; b
)

は有効な ECMAScript 文ではなく、 for ステートメントのヘッダーにセミコロンが必要なため、自動セミコロン挿入によって変更されません。自動セミコロン挿入では、for ステートメントのヘッダーに 2 つのセミコロンのうちの 1 つが挿入されることはありません。起源

return
a + b

自動セミコロン挿入により、次のように変換されます。

return;
a + b;

注: 式 a + b は、return ステートメントによって返される値として扱われません。これは、LineTerminator がそれをトークン return から分離するためです。起源

a = b
++c

自動セミコロン挿入により、次のように変換されます。

a = b;
++c;

注 LineTerminator が b と ++ の間にあるため、トークン ++ は、変数 b に適用される後置演算子として扱われません。起源

if (a > b)
else c = d

は有効な ECMAScript 文ではなく、else トークンの前の自動セミコロン挿入によって変更されません。その時点で文法の生成が適用されなくても、自動的に挿入されたセミコロンは空のステートメントとして解析されるためです。起源

a = b + c
(d + e).print()

2 行目から始まる括弧で囲まれた式は、関数呼び出しの引数リストとして解釈される可能性があるため、自動セミコロン挿入によって変換されません。

a = b + c(d + e).print()

割り当てステートメントを左括弧で開始する必要がある状況では、セミコロンの自動挿入に頼るのではなく、前のステートメントの最後に明示的なセミコロンを提供することをプログラマーが推奨します。

于 2012-10-05T12:37:27.743 に答える
0

Christoph が指摘しているように、return ステートメントはすべてのブラウザーで正しく機能します。コンピュータ用ではなく人間用に、少なくとも and 演算子を別の場所に配置することで、さらに明示的にすることを好みます。

return a &&
       b &&
       c;

この場合、自動化されたセミコロンが大混乱を引き起こすかどうか、一瞬たりとも考える必要はありません。私はこれを JavaScript にのみ好んでいます。元のコードの方が読みやすいです。

于 2012-10-05T12:35:45.000 に答える