ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript のスコープ チェーンの詳細な紹介 (例付き)

JavaScript のスコープ チェーンの詳細な紹介 (例付き)

不言
不言転載
2018-10-19 15:35:072348ブラウズ

この記事では、JavaScript のスコープ チェーンについて詳しく説明します (例を示します)。必要な方は参考にしていただければ幸いです。

概要

JavaScript の実行可能コードには、その実行コンテキストがあります。実行コンテキストには、次の 3 つの重要な要素があります。 #変数オブジェクト

  1. スコープチェーン

  2. this

  3. このうち、変数オブジェクトはコンテキスト内の変数宣言と関数宣言のコレクション。

    これは、変数オブジェクトを保持している人を示します。これは常に現在のコンテキストを指します。
スコープ チェーンは、変数と関数の可視性とライフサイクルを制御します。


1. スコープ チェーン

JavaScript エンジンは、変数識別子に対応するバインディングを検索するときに、最も内側のスコープから検索を開始します。内部スコープが見つからない場合は、親スコープを検索し、最初に一致する識別子が見つかったときに停止します。これは、JS のスコープ チェーンです。

var name = "global";
function func1() {
    var name = "outter";
    function func2() {
        var name = "inner";
        console.log(name);
    }
    func2();
}

func1() // "inner"

console.log(name)

ステートメントでは、JS が

name

変数識別子のバインディングを検索するときに、func2 内から外部関数 最上位レベルまで変数宣言を探します。最終的には、最も近い「内部」値のみが取得され、最初の値が見つかったときに検索が停止します。これは「シャドウイング効果」と呼ばれます。 2. 作成と実行フェーズ

各関数には内部属性 [[scope]] があり、スコープ チェーンは実行コンテキストに関連付けられます。関数を定義すると、スコープ チェーンは親コンテキスト内のすべての変数オブジェクトをリンクします。

var a = 1;
var b = 3;
function foo(){
  var a = 2;
  bar(4);
  function bar(param){
    console.log(a+param)
  }
}


foo.[[scope]] = [
  globalContext.VO // a, b
];

bar.[[scope]] = [
    fooContext.AO, // a
    globalContext.VO // a, b
];

もう一度:

関数の実行には作成フェーズと実行フェーズがあります。変数オブジェクトの値はその時々で異なります。

関数作成フェーズ

一般に、スコープ チェーンは親変数オブジェクト (変数オブジェクト) (スコープ チェーンの先頭)、関数自身の変数 VO、またはアクティブ オブジェクトです。 (アクティベーションオブジェクト) がリストを形成します。

var a = 2;
function foo() {
    var b = 3;
    console.log(a+b);
}
foo() // 5

もちろん、最終的な結果出力が 5 であることはわかっていますが、作成フェーズ中に興味深いことがあります。まず第一に、変数はグローバル環境の変数に属し、b は変数に属します。 foo 関数環境の変数に、作成フェーズでは両方の値が未定義です。

globalContext.VO = {
    a: undefined
}

fooContext.VO = {
    b: undefined
}
foo コンテキストには a が含まれておらず、foo はスコープで見つかった a であることがわかります。 。つまり:

fooContext = {
    [[scope]]: {
        // 父级的变量对象
    }
}

現在の実行コンテキストの [[scope]] には、すべての親コンテキスト内の変数オブジェクトのリストが含まれます。

関数実行フェーズ

関数実行フェーズに入ると、関数コンテキストは現在の実行コンテキスト内の変数オブジェクトをアクティブ オブジェクトに変換し、スコープ内に配置します。チェーンの終わり、最後に変更された変数値。

scope = [AO].contat([[scope]])

したがって、最終的に変数を検索するときは、常に最も内側の実行コンテキストから開始して、バブルアップして外側に向かって検索します。

3. スコープ チェーンを拡張する

JS では、with および try catch キーワードを使用してスコープ チェーンを指定します。読み取りオブジェクトがスコープ チェーンに追加されます。 キャッチの場合、例外オブジェクトは可変オブジェクトにプッシュされ、スコープの先頭に配置されます。

With と try catch はどちらも、現在のスコープでアクセスできる変数オブジェクトの数を増やすため、スコープ チェーンを拡張したものとみなされます。

4. スコープ チェーンとプロトタイプ チェーン

スコープ チェーンの機能は、識別子を見つけ、スコープ チェーンに沿ってバブルアップして検索し、Stop を見つけることです。最初の1つ。 プロトタイプ チェーンは、オブジェクトのプロパティを検索するために使用されます。一般的なプロトタイプ チェーンは、プロパティが見つかると検索を停止します。見つからない場合は、デフォルトで未定義になります。

5. クロージャ

変数は実行後、メモリ内でガベージ コレクションされますが、この時点で変数が他のスコープにある場合、または他のコンテキストのスコープチェーンに参加した後も変数にアクセスし続けることができるこの動作をクロージャと呼ぶと言われています。

function foo() {
    var a = 1;
    function bar (){
        return a;
    }
    return bar;
}

var other = foo();
other();  // 1
foo 関数の実行後、内部変数はクリアされるはずですが、返された関数は変数 a を参照しているため、引き続き変数 a にアクセスでき、これがクロージャを構成します。

概要

スコープ チェーンは、すべての親コンテキストの変数オブジェクトのリストであり、グローバル コンテキストに至るまで内部でコンテキスト ルックアップを実行して識別子を見つけるために使用されます。

以上がJavaScript のスコープ チェーンの詳細な紹介 (例付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。