次のコード:
リーリー
印刷時には未定義になると思っていました。
私の理解では、b = 2 は var を使用していないため、グローバル変数を宣言しています。変数が宣言されているため、変数宣言の昇格が行われます。なぜ ReferenceError: b is not registered になるのでしょうか?
そして var:
を追加してみてください
リーリー
つまり、var を使用するか省略するかは、ローカル宣言とグローバル宣言の違いだけではないようです?
初心者として、アドバイスをお願いします。ありがとうございます。
リーリー
コードの実行には常に順序があります。 。 。
追加ポイント:
直接
b = 2
这种创建全局变量的方式,其实质是变为全局对象上的一个属性,即window.b = 2
なので、昇格または非昇格はありません。var を使用して宣言された変数には宣言の昇格があります。自分で質問して答え、さらに 1 つ追加してください:
mdn でこの文を見つけました:
この文は、グローバル変数 b が a のようにプロモートされない理由についての私の混乱を説明しています。 a は宣言された変数ですが、 b は実行中にのみ定義される未宣言の変数であるため、実行前に昇格されません。
原文: https://developer.mozilla.org...
事前申告となります
リーリーはコンパイラによって
として解釈されます リーリーそして、undeclared/unknown は昇格される可能性がないため、使用されるとすぐにエラーが報告されます
これらのスコープの問題については、「あなたが知らない Javascript」(第 1 巻) を読むことができます。すべて上記で説明しています
エンジン---
JavaScript プログラム全体のコンパイルと実行プロセスを最初から最後まで担当します。
コンパイラー---
エンジンの友人であり、構文分析とコード生成を担当します。
スコープ ---
エンジンのもう 1 つの友人。宣言された識別子 (変数) で構成される一連のクエリを収集して維持し、現在実行中のコードがこれらの識別子に与える影響を決定する非常に厳密なルールのセットを強制します。アクセス権。
var a = 1;
実際、エンジンはここに 2 つの完全に異なる宣言があると考えます。1 つはコンパイル時にコンパイラーによって処理され、もう 1 つは実行時にエンジンによって処理されます。
var a=1 分解
var a に遭遇すると、コンパイラーは同じスコープのコレクション内にこの名前の変数がすでに存在するかどうかをスコープに尋ねます。そうである場合、コンパイラは宣言を無視してコンパイルを続行します。そうでない場合は、現在のスコープのコレクションで新しい変数を宣言し、それに a という名前を付けるようにスコープに要求します。
次に、コンパイラーは、実行時にエンジンを実行するために必要なコードを生成します。これらのコードは、a=1 の代入操作を処理するために使用されます。エンジンは実行中、まず現在のスコープ コレクションに a という変数があるかどうかをスコープに問い合わせます。存在する場合、エンジンはこの変数を使用し、存在しない場合は変数を探し続けます。