パンくずのjavascript宣言期間と実行期間の物語

2533 ワード

jsでは万物がオブジェクトであり、特殊なオブジェクト(functionタイプ)は宣言と実行時に奇妙なことが起こります.以下のようにします.
function a(){

    var id = 1;    

    function b(){

        alert(++i);              

    }

  return b;

}

var c = a();


  
上記のコードは、グローバル役割ドメインでaを宣言したものです.
これらの概念は、関数aの定義から実行までのプロセスを例に挙げて述べる.
  • 関数aを定義すると、js解釈器は、関数aの役割ドメインチェーン(scope chain)をaが存在する「環境」を定義するように設定し、aがグローバル関数である場合、scope chainにはwindowオブジェクトのみが存在する.
  • 関数aが実行されると、aは対応する実行環境(excution context)に入る.
  • 実行環境を作成する過程で、まずaにscope属性、すなわちaの役割ドメインを追加し、その値は第1ステップのscope chainである.すなわちa.scope=aの役割ドメインチェーンである.
  • 環境を実行すると、アクティブなオブジェクト(call object)が作成されます.アクティブなオブジェクトも属性を持つオブジェクトですが、プロトタイプはなくJavaScriptコードで直接アクセスできません.アクティブオブジェクトを作成したら、aの役割ドメインチェーンの最上位にアクティブオブジェクトを追加します.このときaの役割ドメインチェーンには、aのアクティブオブジェクトとwindowオブジェクトの2つのオブジェクトが含まれている.
  • 次は、アクティブなオブジェクトにargumentsプロパティを追加し、関数aを呼び出すときに渡されるパラメータを保存します.
  • 最後に、すべての関数aのパラメータと内部の関数bの参照もaのアクティブオブジェクトに追加される.このステップでは、関数bの定義が完了するので、ステップ3のように、関数bの役割ドメインチェーンは、bが定義された環境、すなわちaの役割ドメインとして設定される.(したがって、bの役割ドメインはbのアクティブオブジェクト-->aのアクティブオブジェクト-->グローバルwindowオブジェクト)
  •  
    コードvar c=a()に戻ります.このときa()の戻り値b関数をcに向け,cはaの内部プライベート属性iに不思議にアクセスできるようになった,これが不思議な閉パケットである.
    関数は呼び出されたときに閉じた環境を作成する特性を有するため、場合によっては「閉じたパッケージ」とも呼ばれる.
    (
    閉包自己理解:
    閉パッケージは抽象的な概念であるべきで、functionが実行時に作成する閉じた環境を指し、この環境は彼の内部関数だけがアクセスできる.
    言い換えれば、内部関数は閉パッケージでのみ外部役割ドメインにアクセスできます.
    閉包回収については,他のオブジェクトと同様に参照されていない場合に回収されるはずである.(すなわち、内部関数が外部参照され、外部参照が生存している場合、閉パケットは回収されない).
    新しい理解は、閉パケットはfunction役割ドメインの1つ(もう1つはグローバル役割ドメイン)であり、参照された親役割ドメインのプロパティの場合にのみ閉パケットが存在し、functionライフサイクルoverの前に親役割ドメインのプロパティもメモリに保存されて解放されません.(よし、カバンを閉じるのは何なのか疑問だが、何も重要ではないようだね.その特性を理解して、使えばいいのに、それが何なのか、時間は教えてくれるはずだ)
    )
     
    実行期間にはもう一つ補充しなければならないのがnewという不思議なキーワードです.
     
    関数が通常実行されると、次のようになります.
    function a(){
    
      var id = 1;    
    
       return id;
    
    }
    
    
    
    function b(){
    
      alert(hello);
    
    }
    
    var c = a();   //return 1;
    
    var d = b();   //return underfined;
    
    //         ,       
    
    //       underfined,   return;     underfined
    
    

      
    関数が特殊に実行されると、次のようになります.
    function a(){ 
    
      this.id = 1;    
    
    }
    
    a.prototype.name = "tianxia";
    
    function b(){
    
      alert(hello);
    
      return;
    
    }
    
    var c = new a();   //return {id:1,name:"tianxia"};
    
    var d = new b();   //return underfined;
    
    //           new      ,                prototype      ,  this           。
    
    //     this  ,              。
    
    

      
    ps:はい、またいくつかの理論を記録したもので、前の文はただ1つのおかずの個人的な理解で、もし問題があれば、多くの指摘をしてください.