JavaScriptにおけるthisの使い方

6080 ワード

thisがグローバルに呼び出されたときに指すのは、グローバルオブジェクトです.thisは関数で呼び出したときに、関数のオブジェクトを指します.関数の呼び出しは異なる場合にあります.
1.    ,       this      
2.       ,  this     
3.    ,  this         
4.call/apply  this  

thisはJavascript言語のキーワードです.関数が動作する時に自動的に生成される内部オブジェクトを表します.関数の内部でのみ使用できます.例えば、
  function test(){
    this.x = 1;
  }
関数を使う場合によって、thisの値が変わります.しかし、一つの原則があります.つまり、thisとは、関数を呼び出す対象のことです.以下は四つの状況に分けて、thisの使い方を詳しく説明します.
状況一:純粋な関数呼び出し
これは関数の最も一般的な使い方で、グローバルコールに属していますので、thisはグローバルオブジェクトglobal/windowを表します.下記のコードを見てください.その結果は1です.
  function test(){
    this.x = 1;
    alert(this.x);
    alert(this === window);
  test(); 
    // 1
    //true
thisが全体の対象であることを証明するために、コードを変更します.
  var x = 1;
  function test(){
    alert(this.x);
  }
  test(); // 1
運転結果はまだ1です.もう一回変えます
  var x = 1;
  function test(){
    this.x = 0;
  }
  test();
  alert(x); //0
関数test()を呼び出した後、this.x文を実行しますが、ここのthis.xはグローバルxを指していますので、グローバルのx=1はこのときx=0になりますので、最後のalert(x)にデータ0があります.ここから関数のthis.xはグローバル変数xの中を指すことが分かります.
パラメータの関数なら?次の例を見てみましょう.
var a = 20;
function fun(a){
    this.a = 1;
    console.log(a);
    console.log(this.a);
};
fun(10); 
//10
//1
関数にパラメータがある場合、thisは依然としてグローバル変数を指しています.パラメータとは関係なく、上の表記は以下のようになります.
var a = 20;
function fun(b){
    this.a = 1;
    console.log(b);
    console.log(this.a);
};
fun(10); 
//10
//1
this.aをthis.bに変えたら?じゃ、this.bは大域の変数ですか?それとも関数の変数ですか?
var a = 20;
function fun(b){
    this.b = 1;            //   var             b,    1
    console.log(b);        //10         b
    console.log(this.b);   //1         b
};
fun(10);
console.log(b); //1        b
JavaScriptでは、大域関数でvarで定義されていない変数は大域変数であると規定されていますので、ここのthis.bは大域を定義した変数bに相当しますので、最後に変数bをプリントできます.
次の二つの関数が分かりますよね.
var a = 20;
function fun(a){
    this.a = 1;
    console.log(a)
};
console.log(a);//20     this.a=1    ,    a   20
fun(10);//10

var a = 20;
function fun(a){
    this.a = 1;
    console.log(a)
};
fun(10);//10
console.log(a);//1   this.a=1    ,    a  1
ケース二:対象方法としての呼び出し
関数はまた、あるオブジェクトの方法として呼び出すことができます.この場合、thisはこの上位オブジェクトを指します.
  function test(){
    alert(this.x);
  }
  var o = {};
  o.x = 1;
  o.m = test;
  o.m(); // 1
あるいは対象の字面量で作成する方法は分かりやすいですが、同じ意味です.
var pet = {
    words : 'my dear',
    speak : function(){
        console.log(this.words);   //my dear
        console.log(this === pet); //true
    }
}

pet.speak();
状況三はコンストラクタとして呼び出される.
構造関数とは、この関数を通して新しいオブジェクトを生成することです.このとき、thisはこの新しいオブジェクトを指します.
  function test(){
    this.x = 1;
  }
  var o = new test();
  alert(o.x); // 1
運転結果は1です.この時のthisが全体の対象ではないことを示すために、コードを変更します.
  var x = 2;
  function test(){
    this.x = 1;
  }
  var o = new test();
  alert(x); //2
実行結果は2で、グローバル変数xの値はまったく変わっていないことを示しています.もう一つの現実的な応用の中の例を見にきます.
function Pet(words){
    this.words = words;

    this.speak = function(){
        console.log(this.words);
        console.log(this)
    }
}

var cat = new Pet('Miao');
cat.speak();
// nwe       cat ,cat      word   speak  , cat.speak()   this    cat    
// Miao
//Pet { words: 'Miao', speak: [Function] }
ケース4 apply、コールコールコール
apply()は関数オブジェクトの一つの方法で、関数を変更する呼び出しオブジェクトとして機能し、最初のパラメータは変更後の呼び出しの対象を表します.したがって、thisとは、この最初のパラメータのことです.var x=0function test(){alert}var o={}o.x=1o.m=testo.m.apply()//0 apply()のパラメータが空の場合は、グローバルオブジェクトをデフォルトで呼び出します.そのため、この場合の運転結果は0で、thisが全体のオブジェクトを指すことを証明しています.最後の行のコードをo.m.applyに変更したら(o)//1運転結果が1になりました.この時のthisが対象であることが証明されました.
アプリには、2つの実際のアプリケーションシーンがあります.1.オブジェクトの中で、呼び出し時にthisの指向が変化します.上記のように、次の例が分かりやすいかもしれません.
var pet = {
    words : 'my dear',
    speak : function(say){
        console.log(say + ' ' +this.words)
    }
}

pet.speak('hello');//hello my dear

//  apple     this   
var dog = {
    words :'wang'
}
pet.speak.call(dog,'hello');//hello wang
pet.speak('hello')//hello my dear
2.継承を実現する時の構造関数--定義時にthisの方向を変更する
function Pets(words,sex){
    this.words = words;
    this.sex = sex;
    this.speak = function(){
        console.log(this.words + ' ' + this.sex)
    }
}

function Dog(words,sex){
    //Pets.call(this, words, sex);
    //Pets.apply(this,[words, sex])
    Pets.apply(this,arguments)
}

var dog  = new Dog('wang','girl')
dog.speak();//wang,girl
いくつかの私たちが区別できないthisが指している状況があります.
var name = "The Window";
var object = {
 name : "My Object",
 getName: function(){
 return this.name;
 }
}; 
object.getName(); //"My Object"
ここでのget Nameメソッドはthis.nameの値だけを簡単に返しますが、呼び出したオブジェクトはobjectなので、My Objectに戻ります.中に入れると閉め切りですか?次のコードを見てください
var name = "The Window";
var object = {
   name : "My Object",
   getNameFunc : function(){
       return function(){
           return this.name;
       };
   }
};
alert(object.getNameFunc()()); //"The Window"(       )
この問題をどう解決しますか?
var name = "The Window";
var object = {
   name : "My Object",
   getNameFunc : function(){
       var that = this;// this   that
       return function(){
           return that.name;
       };
   }
};
alert(object.getNameFunc()()); //"The Object"
thisをthatに与えて、これで解決します.
JavaScriptイベントでもよくこのような状況が発生します.下記のコードを見てください.
var box = document.getElementById('box');
box.onclick = function(){
    console.log(this.id);//box
    function fun2(){
        console.log(this.id);//  
        //fun2()   id,           id
    };
    fun2();
}
この問題に対して私達の解決方法も同じです.
var id = '  ';
var box = document.getElementById('box');
box.onclick = function(){
    console.log(this.id);//box
        
        var that = this;
    function fun2(){
        console.log(tha.id);//  
    };
    fun2();
}
参考資料:1.『JavaScriptのthis用法』--阮一峰