本題でJavaScriptの役割領域を説明します.

4150 ワード

スコープ
作用域を理解するために、跪いて大神のブログを何編も読みました.やっと少し知っています.
1.テーマ
その中で、こんな問題を見ました.
 function factory() {
     var name = 'laruence';
     var intro = function(){
          console.log('I am ' + name);
          console.log('I am ' + age + "years");
     }
     return intro;
}
 
function app(para){
     var name = para;
     var age = 20;
     var func = factory();
     func();
}
 
app('eve');
運転結果は:
I am laruence
    :Uncaught ReferenceError: age is not defined
スコープを理解しないで、私も正しい答えを出しました.しかし、私はインターネット上のオオカミさんの役割領域に対する解説を見てから、この問題を見に来ました.見れば見るほど、経典を読めば読むほど、最初は正しいことができます.純粋な運です.この問題のスコープを描いてから、やっとスコープの入門を感じました.
2.図解スコープ
(1)JSエンジンは、実行可能なコードの一部に入るには、次の3つの初期化作業を完了する必要があります.
  • は、グローバルオブジェクト(Global Object)を作成します.グローバルオブジェクトは、作成時に、Math、String、Date、documentなどの一般的なJSオブジェクトをその属性とします.もう一つの属性のwindowがあります.windowを自分に向けて、windowを通じてこの全体の対象を訪問することができます.
  • は、1つの関数が実行されると、その関数の実行環境が実行環境スタックの上部に押し込まれ、実行権が取得される実行環境スタックを構築する.この関数が実行されると、その実行環境はまたこのスタックの上部から削除され、実行権を元に環境を返します.
  • は、グローバル実行環境ECを作成し、このグローバル実行環境ECを実行環境スタックに押し込む.
  • は、ECに関連するグローバル変数オブジェクトVOを作成し、VOをグローバルオブジェクトに向ける.VOにはグローバルオブジェクトの固有の属性だけでなく、グローバルに定義された変数と関数も含まれています.また、関数Aを定義する際に、Aに内部属性scopeを追加し、scopeをVOに向けました.各関数は定義する時、関連するscope属性を作成します.scopeはいつも関数を定義する時にある環境を指します.
    画像の説明
  • (2)app('eve')に入る実行時
  • は、関数appの実行環境EC(a)を作成し、その後、EC(a)が実行環境スタックの上部に押し込み、実行権を取得する.
  • は、関数appのスコープチェーンを作成する.javascriptでは、各実行環境には、識別子解析のための機能ドメインチェーンがあり、実行環境が作成されると、そのスコープチェーンは現在の実行関数のscopeに含まれるペアに初期化される.
  • は、現在の関数の活動対象AO:AOに関数のイメージ、argmentsオブジェクト、thisオブジェクト、および局所変数および内部関数の定義を作成し、AOを作用領域チェーンの先端に押し込む.関数Bを定義する際には、JSエンジンも同様にBにscope属性を追加し、scopeを定義関数Bを指した場合の環境を定義し、関数Bを定義する環境はAの活動対象AOであり、AOはチェーンテーブルの先端に位置し、チェーンテーブルが最初の尾につながる特徴があるため、関数BのscopeはAの全作用領域チェーンを指す.
    画像の説明
  • (3)factoryに入る場合
  • は、関数factoryの実行環境EC(f)を作成し、その後、EC(f)を実行環境スタックの上部に押し込み、実行権を取得する.
  • は、関数factoryのスコープChin(f)を作成する.javascriptでは、各実行環境には、識別子解析のための機能領域チェーンがあり、実行環境が作成されると、その作用領域チェーンは現在の動作関数のscopeに含まれるオブジェクトに初期化される.
  • は、現在の関数の活動対象AO(f)を作成します.AOには関数のモダリティ、argmentsオブジェクト、thisオブジェクト、および局所変数および内部関数の定義が含まれています.その後、AO(f)は、スコープの先端に押し入れられます.JSエンジンは、関数introを定義する際に、同じくintroにscope属性を追加し、scopeを定義関数introを指した場合の環境を指します.関数introを定義する環境はfactoryの活動対象AO(f)であり、AO(f)はチェーンテーブルの先端に位置しています.チェーンテーブルの先頭につながる特徴があります.従って関数introのscopeはfactoryの全作用領域鎖を指している.
    画像の説明
  • (4)Fnc()に入ると関数factoryが実行され、introの参照に戻り、変数funcに値が与えられ、Fnc()が実行されるとintro()に相当します.
  • は、関数introの実行環境EC(i)を作成し、その後、EC(i)を実行環境スタックの上部に押し込み、実行権を取得する.この時実行環境スタックには、グローバル実行環境、関数アプリの実行環境、関数intro、introの実行環境が三つあり、全体実行環境はスタックの一番下にあります.
  • は、関数introの作用ドメインチェーンScope Chin(i)を作成し、関数introのscopeに含まれるオブジェクト、すなわちfactoryの作用ドメインチェーンを含むものとして初期化する.
  • は、関数introのアクティブオブジェクトAO(i)を作成し、introのargmentsオブジェクトおよびthisオブジェクトをAO(i)の属性とする.
    画像の説明
  • func()を実行すると、その作用ドメインチェーンはVO(G)です.
  • name属性が読み取られた時、AO(i)オブジェクトにはname属性がなく、作用領域チェーンに沿ってAO(f)に行き、name属性が読み取られ、値は「laruence」である.
  • age属性が読み取られると、AO(f)だけがage属性を定義していますが、AO(f)は作用領域チェーン上にないので、シナリオエラーUncaught ReferenceError: age is not definedに報告します.age属性は未定義です.これはまた側面から,上の作用分域鎖解析が正しいことを証明した.
  • 実行が完了しました.終了します.
    3.Javascriptにおけるスコープ
  • JavaScriptの関数は、それらが実行される作用領域ではなく、定義されたスコープ内で実行される.
  • は、JSにおいて、関数を呼び出すたびに、関数内のスコープに入り、関数から返されると、呼び出される前のスコープに戻る.
  • は、javascriptにおいて、それぞれの関数に実行環境があり、関数が実行されると、その関数の実行環境が実行環境スタックの上部に押し込まれ、実行権が取得される.この関数が実行されると、その実行環境はまたこのスタックの上部から削除され、実行権を元に環境を返します.
  • 各関数は、定義された時に、関連するscope属性を作成します.scopeは常に関数を定義する時にある環境を指します.
  • は、Javascriptにおいて、各実行環境には、識別子解析のための独自の作用ドメインチェーンがあり、実行環境が作成されると、その作用ドメインチェーンは、現在の実行関数のscopeに含まれるオブジェクトに初期化される.
  • は、ドメインチェーンの役割を果たし、識別子解析が発生すると、現在のscope chainリストの各アクティビティオブジェクトの属性を逆方向に調べ、同名が見つかったら戻ってきます.見つけられませんでした.この識別子は定義されていません.
  • グローバルオブジェクト(Global Object)は、このオブジェクトの大域は一つしか存在しません.属性はどこにでもアクセスできます.アプリケーションのライフサイクル全体に伴って存在します.グローバルオブジェクトは、作成時に、Math、String、Date、documentなどの一般的なJSオブジェクトをその属性とします.
  • 活動対象AOは、ここでの活動対象が変数オブジェクトの役割を果たしています.関数内の呼び方が異なるだけです.そしてAOは作用するドメインチェーンの先端に押し込まれます.
  • 参考文献
  • javascript定義から実行まで、あなたが知らないこと
  • Javascript作用ドメイン原理