this、callとappy

3201 ワード

1:this
多くの言語と同じように、javascriptのthisはいつも一つのオブジェクトを指していますが、具体的にはどのオブジェクトが実行時に関数に基づいて実行される環境に動的に結合されていますか?
2:thisの指向
あまり使われていないeverlとwithを除くと、thisの指し示しは大体以下の4つに分類されます.
  • :オブジェクトとしてのメソッド呼び出し
  • :一般関数として呼び出される
  • :コンストラクタ呼び出し、
  • :Function.prototype.callまたはFunction.prototype.appy呼び出し
  • 2.1:オブジェクトとしてのメソッド呼び出し
    関数をオブジェクトとする方法が呼び出されると、thisはオブジェクトを指す.
    var obj = {  
          a: 1,    
          getA:function () {        
            alert(this === obj);//true
            alert(this.a)//a
          }
     };
    obj.getA();
    
    2.2:一般関数として呼び出す
    関数がオブジェクトの属性として呼び出されない場合は、通常の関数で呼び出します.このときのthisは常にグローバルオブジェクトを指します.ブラウザーの中で全体の対象はwindowです.
    var name = "globalName";
    var getName = function () {
        return this.name;
    };
    console.log(getName());//  :globalName
    //      :
    var myObject = {
        name:"jiankui",
        getName:function () { 
           return this.name;
        }    
    }; 
    var getName = myObject.getName ; 
     console.log(getName())//  :globalName
    
    2.3:コンストラクタの呼び出し
    いくつかの内蔵の関数を除いて、ほとんどのjavascript関数はコンストラクタとして使用できます.コンストラクタの外観は普通の関数と同じです.違いは呼び出しの方式です.new演算子で関数を呼び出すと、変更関数は通常オブジェクトに戻ります.コンストラクタのthisはこの戻りの対象を指します.
    var myClass = function () {
        this.name= "jiankui";
    };
    var obj = new myClass();
    console.log(obj.name);//jiankui
    
    しかし、newコンストラクタを使う時に、もう一つの問題に注意しなければなりません.コンストラクタが明示的にobjectタイプのオブジェクトを返すと、今回の計算結果は最終的にこのオブジェクトに戻ります.
    var myClass = function () {
      this.name= "jiankui";
      return {//         
          name: "jiankui2"
      }
    };
    var obj = new myClass();
    console.log(obj.name);//jiankui2
    
    コンストラクタが明示的に任意のデータを返していない場合、または非オブジェクトタイプのデータを返しても、上記のような迷惑はかかりません.
    var myClass = function () {
      this.name= "jiankui";
      return  "jiankui2";
    };
    var obj = new myClass();
    console.log(obj.name);//jiankui
    
    2.4:Function.prototype.callまたはFuntions.prototype.appy呼び出し
    一般的な関数呼び出しと比較して、Funtions.prototype.callまたはFuntion.prototype.applyで、着信関数のthisを動的に変えることができます.
    var obj1 = {
    name:"jiankui",
    getName:function () {
        return this.name;
    }};
    var obj2 = {
        name:"jiankui2"
    };
    console.log(obj1.getName());//jiankui
    console.log(obj1.getName.call(obj2));//jiankui2
    
    3:失われたthis
    これはよくある問題です.まずコードを見ます.
    var obj = {
    name:"jiankui",
    getName:function () {
        return this.name;
    }};
    var getName2 =obj.getName;
    console.log(obj.getName());//jiankui
    console.log(getName2());//undefind
    
    Obj.get Name()を呼び出すと、getNameは対象となる方法で呼び出され、2.1によると、thisはObjオブジェクトを指すので、Obj.get Name()はjiankuiを出力する.もう一つの変数get Name 2()でOB j.get Nameを引用し、get Name 2()を呼び出した場合、2.2によると、この時は普通の関数として呼び出され、thisはwindowを指しますが、私たちのwindowは定義されていませんので、undefinedとなります.
    4 calとappy
    appryは2つのパラメータを受信して、最初のパラメータは関数の体内のthisオブジェクトの指向を指定しています.第2のパラメータは1つのバンドの下付きセットであり、配列とクラスの配列であってもいいです.
    var func = function (a, b, c) {
       console.log([a, b, c]);//[1,2,3]
    };
    //          abc    
    func.apply(null,[1,2,3]);
    
    callから入ってきたパラメータの数は固定されていません.appyと同じです.最初のパラメータも関数の体内を表すthis方向です.二つ目のパラメータから順に関数に入力されます.
    var func = function (a, b, c) {
       console.log([a, b, c]);//[1,2,3]
    };
    func.call(null,1,2,3);