Pythonの改行の処理は、JavaScriptの自動セミコロンとどのように異なりますか?


41

Javascriptには自動セミコロン挿入と呼ばれる機能があり、基本的にパーサーが無効なトークンに遭遇し、その前の最後のトークンが改行であった場合、パーサーは改行があるセミコロンを挿入します。これにより、基本的にすべてのjavascriptコードをセミコロンなしで記述できますが、主にreturnキーワードがあり、次に改行で返す値がある場合は、いくつかのエッジケースに注意する必要があります。

function test(){
    // This will return 'undefined', because return is a valid statement
    // and  "john" is a valid statement on its own.
    return 
          "john"
}

これらの落とし穴があるため、「自動セミコロン挿入は悪」、「Javascriptでは常にセミコロンを使用」などのタイトルの記事が多数あります。

しかし、Pythonでは誰もセミコロンを使用せず、まったく同じ落とし穴があります。

def test():
    # This will return 'undefined', because return is a valid statement
    # and  "john" is a valid statement on its own.
    return 
    "john"

まったく同じように動作しますが、Pythonの動作を恐れる人はいません。

JavaScriptの動作が悪い場合は、それらを簡単に回避できるほど十分ではないと思います。新しい行に+値を返しますか?人々は本当にそれをたくさんしますか?

意見はありますか?javascriptでセミコロンを使用していますか?その理由は?


3
まったく同じようには機能しません。JavaScriptで改行が必要な場所にセミコロンを挿入する必要はありません。このウィキペディアのページの 2番目の例を参照してください。その例では、改行がある場所にセミコロンは挿入されません。
リード

1
私のポイントは、セミコロンを使用してもセミコロンを使用してもまったく同じように機能しないということではなく、javascriptとpythonのエッジケースが同じであるということでした。確かに、何が起こっているのかを知る必要があるいくつかのエッジケースがあります。私は、件名に読んだベスト記事:inimino.org/~inimino/blog/javascript_semicolons
はEinar Egilsson

4
文章でピリオドを使用するのと同じ理由で、JavaScriptにセミコロンを挿入します。通訳は通常、文がなくても文の意味を理解することができますが、それは単なる悪い形式です。
JD Isaacks

3
あなたの例で有効なPythonを書くことを検討するかもしれません。コメントインジケータは#、「//」ではなく、です。
アーロンデュフォー

2
「明示的は暗黙的よりも常に良い」

回答:


62

理由は、Pythonでは改行がコード行を明確に分離する方法だからです。これは設計によるものであり、この仕組みは徹底的に検討されています。その結果、Pythonコードは、(改行を除いて)特別なステートメント終了マーカーなしで完全に読み取り可能で明確です。

一方、JavascriptはCのような構文を念頭に置いて設計されており、ステートメントは常にセミコロンで終了します。言語をエラーに対してより寛容にするために、コードを修正するために余分なセミコロンがどこに行くべきかを推測しようとします。これは一種のCライクな構文に後付けされているため、常に期待どおりに動作するとは限らず(スクリプトインタープリターが間違った推測をすることもあります)、かなり直感に反するコードを作成できます。

または、「明示的は暗黙的よりも優れている」という点で議論します。Pythonでは、改行はすでに完全に明示的ですが、Javascriptでは曖昧なので、セミコロンを追加して明示的にします。


3
ああ、逆引用符を使ってコメントにコードを入れることができます。
-tdammers

1
:自動セミコロン挿入が予想外のものをやってしまう例良い例がこれですpastebin.com/aVeWGdya
HoLyVieR

5
Pythonでは、ルールは非常に単純です:閉じられていない複数行の文字列( "" "、 '' ')、閉じられていない辞書({})、閉じられていないリスト([])、またはバックスラッシュがない場合、ステートメントは改行で終了します改行の前にJavaScriptでは、ルールはかなり複雑です。。
アーロン・デュフール

5
99%のエラーをカバーすることは、見つけるのが非常に難しいものだけを残す良い方法です。100%の問題をカバーする簡単なルールがあるので、Pythonでそれらを残しても構いません。
アーロンデュフォー

1
@Aaron:「括弧の閉じられていないセット(())」を忘れました。(括弧はタプルだけに使用されるわけではないため、厳密には「閉じられていないタプル」ではありません。)
JAB

28

Pythonでの動作とは根本的な違いがあると思います。Einar Egilssonからリンクされた「次の行の最初のトークンが同じステートメントの一部として解析できる場合、行末にセミコロンが含まれることはありません」からの引用。

Pythonでは、括弧で囲まれた式のような特定のかなり明白な場合を除き、改行は常にステートメントを終了します。一方、JavaScriptはステートメントを終了する前にできる限り多くの行を解析しようとするため、次のような結果につながる可能性があります。

// Define a function and name it area.
area = function(r) {
    return r * r * 3.14159
}

// Fooled you! We're actually invoking it.
(14)

8
さて、これに面白いひねりを加えました。14を次のようなものに置き換えます。(a + 1) ? do_something() : do_something_else();突然、areaはdo_something()or の戻り値に設定され、do_something_else()非常に混乱してしまいます。
リード

20

本番モードでは、JSファイルを最小化することがよくあります。手段、コメントおよび改行の削除。

セミコロンを使用しないと、Javascriptが壊れます。


8
OK、それは有効です。しかし、ミニマイザーが実際のパーサーである場合、必要に応じて再度挿入することができます。または、改行を削除しないでください。=>改行を保持し、セミコロンを失います。それらはほぼ同じ数なので、失われることはありません。
アイナーエギルソン

2
@Einar Egilsson Closure Compilerは確かにこれを行います。
seriousdev

1
すべてが等しい場合、改行はセミコロンと同じバイト数です。ミニマイザーはすべての新しい行を削除できますが、セミコロンが必要です。それは均等な交換です。
ローガンベイリー

3
@ローガン:それはもちろん、1バイトの改行を想定しています;-)
キャメロン

1
もちろん、Javascriptの代わりにPythonを使用した場合、同じことをするためにWAYを少なくコーディングする必要があります。したがって、セミコロンがインデントよりも数バイト少ないという事実は重要なポイントです。
BlueRaja-ダニーPflughoeft

5

説明どおりには機能しません。

Javascriptには自動セミコロン挿入と呼ばれる機能があり、基本的にパーサーが無効なトークンに遭遇し、その前の最後のトークンが改行であった場合、パーサーは改行があるセミコロンを挿入します。

これは間違っています。例:

return
  1 + 2;

1は完全に有効なトークンですが、パーサーはセミコロンを直後に挿入しreturnます。

ご覧のとおり、セミコロンがどこで発生するかを正確に知ることはできません。

自動挿入の問題は2つあります。

  • 1つは、自動挿入では挿入が必要であると判断できないセミコロンを削除する場合があります。
  • また、セミコロンは、上記のように、意図しない場所に挿入される場合があります。

もちろん、すべてのステートメントの後にセミコロンを使用すると、最初のエラーのソースでのみ役立ちます。

いずれにせよ、今ご想像のとおり、Cのような構文でのセミコロンの自動挿入は悪い考えだと思います。


1
ECMA Scriptの仕様では、どの場合にセミコロンが挿入されるかを明示的に指定しているため、「セミコロンがどこで発生するか正確にはわからない」という行は正しくありません。問題は、場合によっては直感的ではなく、その仕組みを理解していない人に教えるのが難しくなることです。
zzzzBov

1
@zzzzBov:はい、正確な仕様はありますが、コーディング中に誰かが本当にすべてのケースを念頭に置いていますか?本気ですか?プログラマーは怠け者であり、当然です。彼らは、もっと単純なルールがあれば、複雑なルールを覚えておく必要はありません。それで、彼らはそれを覚えなければならないことを回避しようとします。
スヴァンテ

セミコロンを挿入する必要はほとんどないことに同意します。「セミコロンの挿入場所が
わから

1
@Svante:しかし、返された例は、とにかくこれらのルールを知る必要があることを示しています。そこでセミコロンを使用しましたが、それはあなたが望むことをするのを助けませんでした。そのため、言語にこの機能があるため、(1)あらゆる場所にセミコロンを記述し、ルールを把握して何が起こるかを理解する(2)あらゆる場所にセミコロンを記述せず、ルールを理解して何が起こるかを理解するという選択肢があります。選択私は私ではなくセミコロンスキップと思うことを考える
はEinar Egilsson

4

1つの簡単な理由を述べたいと思います。

Javascriptは「kind java-ish」または「kinda C-ish」に見えます。もちろん動的言語なので、見た目は異なりますが、それに直面しています- 中括弧があります。通常、中括弧のある言語にはセミコロンがあります。自然な反射神経が蹴り込み、指を打つ前にセミコロンキーに向かわせますEnter

それどころか、Pythonは一見すればまったく異なって見えます。したがって、「標準の退屈な言語」への類似性は直観的にほとんどまたはまったく形成されず、「pythonモード」に入ると、セミコロンの欠如が自然になります。


2

数があります良い理由のない JavaScriptでセミコロン挿入を使用するには。

これは主に、ECMAScript標準で定義されているセミコロン挿入が場合によっては直感的でないためです。@Svante returnは、改行の使用が問題を引き起こすケースを指摘しています。

彼が言及していないのは、セミコロンを使用している場合にも問題が発生するということです。セミコロンの挿入は、必要かどうかにかかわらず発生するためです。

セミコロン挿入を使用しないもう1つの非常に良い理由は、出力制御です。多くの場合、JavaScriptは本番環境で使用される前に、ミニファイアーを介して実行されます。一部のミニファイヤは自動セミコロン挿入のケースを処理できますが、完全に機能することに頼る理由はありません

さらに、コンテンツ管理システムでは、インラインJavaScriptが自動縮小される場合があります。自動縮小機能がコメントを削除し、各行の先頭と末尾から空白(改行を含む)を削除する場合が多く見られます。

どのツールが選択されているかを選択できない著者にとっては、ほとんどの場合に機能する形式に固執する方がはるかに簡単です。


申し訳ありませんが、ああ、しかし、あなたの第三段落について、私はやる私の最後から2番目の文のことを言及します。:)
スヴァンテ

はい、ツールの問題は有効です(ただし、クロージャコンパイラなど、優れたミニファイヤがこれを処理する必要があります)。しかし、私の意見では、「リターン」の例のようなことを避けるために、とにかくこれらのルールを知る必要があります。そして、ルールを理解したら、特にコード(IMO)を読みやすくするため、この機能を使用することもできます。
アイナーエギルソン

1

セミコロンを使用しないことは、ファイルのJavaScriptファイルを縮小するときの失敗のレシピです。それが私が怖い理由です。


1

JavaScriptでは、自動セミコロン挿入がない場合に構文的に正しいプログラムを作成できます。ASIは、そのプログラムを別の構文的に正しいプログラムに変換します(たとえば、値を返すコードを何も返さないコードに変換する)。Pythonには類似したケースはありません。Pythonでは、ステートメント終了できる改行は、バックスラッシュでエスケープされない限り、ステートメント終了します。技術的には、Javascriptのルールも同様に決定論的であると思いますが、ステートメントを終了するためのJavascriptのルールを1つの文に要約できるかどうかはわかりません。


1

ほとんどの場合、JavaScriptのASIは期待どおりに処理します。ASIが期待どおりに動作しない可能性がある1つの例は次のとおりです。

var i = 0

(function() {
   // do something
})()

これは0、匿名関数で関数を呼び出し、結果を実行すると解釈されます。この場合、おそらく割り当てを行い、その後すぐに匿名関数を実行したいでしょう。

ASIに慣れていない人にとっては、このような問題に遭遇すると非常に混乱する可能性があるため、チームの開発者には常にセミコロンを使用することをお勧めします。

(余談ですが、個人/サイドプロジェクトで作業するときは、他の誰もコードを保守する必要がないことを知っているので、セミコロンを使用しません。)


1

あなたのように、私はそれが少し妄想だと思います。セミコロン挿入のルールは、PythonやCoffeeScriptの場合と同様にJavaScriptでも適切に定義されています。PythonやCoffeeScriptにセミコロンを散らかす人はいないので、JavaScriptの扱いが異なるのはなぜですか?

これは、約10年前の典型的なJavaScriptコードの惨めな状態に対する過剰反応だと思います。JavaScriptは、弱く、バグが多く、,く、良くない言語と見なされていました。それは恥ずかしかった。JavaScriptで良いコードを書くことはできないでしょう!

その後、人々がやって来て、JavaScriptで美しく明確なコードを書くことができることを証明しようとしました。「常にセミコロン使用する」ルールはこの波の一部でした。正直に言うと、いくつかの状況を少し明確にすることができます。

JavaScriptの扱いが異なるのはなぜですか?

慣性があります。また、明示的に構造化されたコードを好む人がしばしばCスタイル言語を好むことも見落としてはなりません暗黙的に構造化されたコードを好む人々は、C言語以外の言語(CoffeeScriptなど)に移行することがよくあります。


0

一貫性を保つために厳密にJavascriptで使用しています。ほとんどの行に

Pythonには、1行に複数のステートメントなどのエッジケースがありますが、javascriptにはそれらがあり、定期的に使用されることがわかるので、使用される標準に準拠しています。

同じ行で複数のステートメントの使用法を見つけることができないため、セミコロンの使用を予見しません。


はい、Pythonの例を修正しました。しかし、ポイントは残ります。Pythonにもセミコロンがあり、すべてのステートメントの後に配置することはできます(各行に複数ある場合は必要です)が、人々はそれらを使用しません。
はEinar Egilsson

0

bundle-fuのようなものを使用し、railsのWebアプリにアセットマネージャーを使用する場合、javascriptのトークンの最後にセミコロンがなければ、ひどく壊れます。そのため、1つを置くことをお勧めします。


さて、ビッグ3、YUI Compressor、Closure Compiler、およびUglifyJSは、すべてセミコロン挿入を行います。JSMinのルビーポートに問題があるのは驚くことではありません。
ベンジャミンアトキン

0

IEの正確なバージョンを思い出せませんが、セミコロンが欠落しているとIEが文字通りエラーになる場合があります。IIRCは、グローバルスコープに次のようなものがある場合です。

var myFunc = function() {
  ...
}

を追加しない場合; 閉じ括弧の後、プログラムはIEのいくつかのバージョンで実際に失敗します。それは、他の理由(Crockfordの推奨事項を常に明示的に使用することを含む)とともに、あらゆる場合に常に明示的に使用するように導きました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.