180

これが Node.js コンソール (4.1.1 および 5.3.0 でテスト済み) では機能するのに、ブラウザー (Chrome でテスト済み) では機能しないのはなぜですか?

このコード ブロックは、ログを記録する無名関数を作成して呼び出す必要がありますOk

() => {
  console.log('Ok');
}()

また、上記Node.js で機能しますが、これは機能しません。

n => {
  console.log('Ok');
}()

これも:

(n) => {
  console.log('Ok');
}()

パラメータが追加されると、実際にSyntaxErrorすぐに呼び出す部分で a がスローされるのは奇妙です。

4

4 に答える 4

2

このような問題が発生する理由は、コンソール自体が、現在対象としているコンテキストのグローバル スコープをエミュレートしようとするためです。また、コンソールに記述したステートメントや式からの戻り値を取得して、結果として表示しようとします。たとえば、次のようにします。

> 3 + 2
< 5

ここでは、式であるかのように実行されますが、文であるかのように記述されています。通常のスクリプトでは値は破棄されますが、ここでは、コードを内部的に壊す必要があり (ステートメント全体を関数コンテキストとステートメントでラップするなどreturn)、発生している問題を含むあらゆる種類の奇妙な影響を引き起こします。

これは、スクリプト内の裸の ES6 コードが正常に動作するのに、Chrome Dev Tools コンソールでは動作しない理由の 1 つでもあります。

Node と Chrome コンソールでこれを実行してみてください:

{ let a = 3 }

ノードまたは<script>タグでは問題なく動作しますが、コンソールではUncaught SyntaxError: Unexpected identifier. VMxxx:1また、次のように表示される、評価されたソースを検査するためにクリックできる形式のソースへのリンクも提供します。

({ let a = 3 })

では、なぜこれを行ったのでしょうか。

答えは、結果を呼び出し元に返してコンソールに表示できるように、コードを式に変換する必要があるということです。これを行うには、ステートメントを括弧で囲んで式にしますが、上記のブロックが構文的に正しくなくなります (式にブロック宣言を含めることはできません)。

コンソールは、コードを賢くすることでこれらのエッジケースを修正しようとしますが、それはこの回答の範囲を超えていると思います. バグを報告して、それが修正を検討するものかどうかを確認できます。

非常によく似たものの良い例を次に示します。

https://stackoverflow.com/a/28431346/46588

コードを機能させる最も安全な方法は、式として実行できることを確認し、SyntaxErrorソース リンクを調べて実際の実行コードを確認し、そこからソリューションをリバース エンジニアリングすることです。通常、戦略的に配置された括弧のペアを意味します。

つまり、コンソールはグローバル実行コンテキストを可能な限り正確にエミュレートしようとしますが、v8 エンジンと JavaScript セマンティクスとの相互作用の制限により、これを解決するのが困難または不可能な場合があります。

于 2016-07-15T09:02:09.993 に答える