いわゆる範囲は、読み書きできるスコープ(エリア)として単純に理解できます。 JSの経験を持つ一部の学生は、「JSにはブロックレベルの範囲がない」と言うかもしれません。グローバルな範囲に加えて、関数のみがスコープを作成できます。スコープの利点の1つは、変数を分離できることです。
JSの範囲を理解するために、いくつかの例を使用しています。
アラート(a); var a = 1;
スコープをまったく知らない学生は、アラートが1であると言うか、エラーを報告する場合があります。しかし、それは実際には未定義です。
これについて言えば、最初にJSが行ごとにコードを解析する前に行われたいくつかの準備について話しましょう。
行ごとにコードを読む前に、JSはいくつかの「予測」作業を行い、事前に「小さなもの」を見つけます。もちろん、「JSパーサー」は何気なくデータを見つけることはありません。VAR、機能、およびパラメーターに従ってそれを見つけます。
「JSパーサー」は比較的「怠zy」です。コードを正式に実行する前に、VARによって宣言された変数を未定義に割り当てます。つまり、VAR A =未定義です。関数全体が、コードがどれだけあるかに関係なく、コードブロックと見なされます。パラメーターは、後で例で言われます。
すべての準備が行われた後、「JSパーサー」は行ごとにコードを実行し始めます。さて、始めた例を分析しましょう。なぜそれが未定義であるのかを理解するのは簡単です。
次の例を見てみましょう
アラート(a); var a = 1;アラート(a); var a = 2;アラート(a);
これを少し分析しましょう
最初の「準備」:パーサーはvarを探します
2行目を読むときa =未定義。
4行目を読むとき、まだa =未定義です。
コードの正式な行ごとの実行:
ファーストラインアラート:未定義
2行目a = 1;
3行目のアラート:1;
5番目の要素アラート:2
以下の例を見てみましょう
アラート(a); var a = 1;アラート(a);関数a(){alert(2); } alert(a); var a = 3;アラート(a);関数a(){alert(4); } alert(a);これを少し分析しましょう
最初に、「Pre-Parse」:パーサーはVAR機能を探します。
2行目を読むときa =未定義。
4行目A = function a(){alert(2);} //すべての関数は、コードを正式に実行する前の関数ブロック全体です。変数が重複した名前に遭遇すると、1つの変数のみが残ります。変数と関数が重複した名前の場合、関数のみが残ります。
6行目を読むとき、a = function a(){alert(2);}
8行目を読むとき、a = function a(){alert(4);}
コードの正式な行ごとの実行:
ファーストラインアラート:function a(){alert(4);}
2行目a = 1; //式は、事前に分類された値を変更できます!
3行目のアラート:1;
機能の4行目は呼び出されません、スキップ。
5番目の要素アラート:1;
行6 a = 3;
7行目のアラート:3
8番目の線関数は呼び出されません、スキップ。
9行目のアラート:3
図に示されているように:
その例を見続けます:
var a = 1; function fn1(){alert(a); //未定義のvar a = 2;} fn1();アラート(a); // 1最初の「準備」:パーサーはVAR機能を探します
最初の行を読むときa =未定義。
2行目を読むときfn1 = function fn1(){alert(2); var a = 2;}
コードの正式な行の実行:最初の行A = 1;
6行目の関数呼び出し、関数範囲を入力し、関数スコープに事前パースを入力してから、行ごとに実行します。
関数内の準備:a = undefined;
実行:アラート:未定義。
a = 2; //この時点では関数範囲内のAのみであり、グローバルではAには影響しません
関数が実行され、グローバルスコープに戻ります。
行7アラート:1;
続く:
var a = 1; function fn1(){alert(a); // 1 a = 2;} fn1();アラート(a); // 2上記の例の唯一の違いは、関数内のAにVARがなく、重要なポイントのみを分析することです。
関数の範囲には、関数の範囲がないため、関数の範囲では、「パーサー」が関数の範囲の上位レベルの範囲を探します(上位レベルと低レベルの関係の決定は、機能が作成された範囲に依存し、どの範囲が作成されますか?この時点で、関数の上位レベルがグローバル範囲です。グローバル範囲ではa = 1なので、この時点で3行目のアラート:1、次に4行目は値を割り当てますが、関数範囲にはAがありません。つまり、グローバル範囲にAを見つけ、グローバル範囲でAを変更するので、A = 2はグローバルスコープ= 2になります。
この点は明確に理解され、VARの違いに注意を払う必要があります。
次:
var a = 1;関数fn1(a){alert(a); //未定義のa = 2; } fn1();アラート(a); // 1この例と前の例の違いは、追加のパラメーターがあることです。パラメーターの関数は、ローカル変数に相当します。つまり、関数の事前分類でvar a =未定義です。したがって、3行目のアラート:未定義で、4行目A = 2は関数スコープのAを変更しますが、これはグローバルコンテキストではAに影響しません。 7回目のアラート:1;
それから:
var a = 1; function fn1(a){alert(a); // 1a = 2;} fn1(a); alert(a); // 1この例は、前の例とは多少異なります。 6行目で関数が呼び出されると、パラメーターが渡されます。6行関数の実際のパラメーターAは、グローバル変数a = 1の1です。関数が実行される場合、2行目A = 1なので、3行目アラート:1、および7行目のアラート:1。
これらの例の違いに注意を払い、それらを混同しないでください。
もう1つ:
var a = 1; function en(){var a = 2; fn();} function fn(){alert(a); // 1} en();fnのaは宣言されておらず、関数が作成されたスコープで値を取得する必要があります。関数の範囲を「呼び出す」のではなく「作成」されます。
PS:JavaScriptの範囲とコンテキストの概念
JavaScriptのスコープとコンテキストは、この言語に固有のものです。これは、柔軟性のおかげでもあります。各関数には、異なる変数コンテキストと範囲があります。これらの概念は、JavaScriptのいくつかの強力な設計パターンに裏付けられています。ただし、これは開発者にも大きな混乱をもたらします。以下は、JavaScriptのコンテキストと範囲の違い、およびさまざまなデザインパターンがそれらをどのように使用するかを完全に明らかにしています。
コンテキスト対スコープ
明確にされる最初の質問は、コンテキストと範囲が異なる概念であるということです。長年にわたり、多くの開発者がこれらの2つの用語をしばしば混同し、もう1つを誤って説明していることに気づきました。公平を期すために、これらの用語は非常に混乱しています。
各関数呼び出しには、それに関連する範囲とコンテキストがあります。基本的に、スコープは関数ベースであり、コンテキストはオブジェクトベースです。言い換えれば、スコープは、関数が呼び出されるたびに変数へのアクセスに関連し、各呼び出しは独立しています。コンテキストは常にキーワードの値です。これは、現在の実行可能コードを呼び出すオブジェクトへの参照です。
上記は、編集者が紹介したJavaScriptの範囲です(推奨)。それがあなたに役立つことを願っています。ご質問がある場合は、メッセージを残してください。編集者は時間内に返信します。 wulin.comのウェブサイトへのご支援ありがとうございます!