Javascriptにおけるthis解析

2648 ワード

JavaScriptを勉強している間に、ずっとthisについての理解が曖昧で、たくさんの資料を調べて分かりました.一緒に分かち合います.
thisの呼び出しは呼び出しの文脈によって決まります.まとめは大体4つの方式に分けられます.
1.関数方式の呼び出し
window.a='window'
function pay(){
    console.log(this.a)
}
pay()//window
JavaScriptで関数が直接呼び出された時も、thisのデフォルトの呼び出し方式です.thisはグローバルオブジェクトに向かって、再度コールバック関数の例を見てみます.
window.a='window'
function pay(){
    function callback(){
        console.log(this.a)
    }
    callback()
}
pay()//window
JavaScriptでは、コールバック関数はずっと煩雑な問題です.thisを処理しないと、関数の対象自体は通常var self=thisを定義します.selfを使ってthisの指向を修正します.
2.対象から外す
window.a='window'
var obj={
    a:'obj',
    getA:function(){
        console.log(this.a)
    }
}
var getA=obj.getA;
obj.getA()//obj
getA()//window
2つの呼び出し方法はいずれもobjに戻りますが、2番目の関数のthisはグローバルオブジェクトを指しています.よく考えてみると、getA=obj.getAのように、objのgetA()の参照割当値をgetAに与えていますが、本質的には関数の呼び出しです.
3.コンストラクタによる呼び出し
window.name='window';
var Student=function(name){
    this.name=name;
}
var leo=new Student('leo');
console.log(leo.name)//leo
構造関数によって直接にオブジェクト自体に向けてthisを呼び出しますが、問題コンストラクタ内でオブジェクトを返すと、thisは戻ってくるオブジェクトを指します.
window.name='window';
var Student=function(name){
    this.name=name;
    return {
        name:'joy'
    }
}
var leo=new Student('leo');
console.log(leo.name)//joy
4.appy、call、bindを利用してthisのハードバインディングを実現する.
開発ではよくこれらの関数を使います.例えば、呼び出し関数のthisの方向を変えます.
window.a='window'
var obj1={
    a:'haha'
}
var obj2={
    a:'heihei'
}
var obj3={
    a:'welcome'
}
function say(){
    console.log(this.a)
}
say();//window
say.call(obj1);//haha
say.apply(obj2);//heihei
var say3=say.bind(obj3);
say3()//welcome
この3つの関数が入ってきた最初のパラメータは同じです.関数を呼び出すにはthisの方向を提供します.関数のthisの方向を任意に変更して、他の関数を借りる方法があります.
//     
var A=function(name){
    this.name=name
    this.getName=function(){
        return this.name
    }
}
var B=function(){
    A.apply(this,arguments)
}
var b=new B('leo');
console.log(b.getName())//leo
//     
var obj={}
Array.prototype.push.apply(obj,[1,2])
console.log(obj)//{0:1,1:2,length:2}
appyを利用して直接に他の関数で定義する方法を使用してもいいです.また、この3つの関数の違いはapplyとcallの使用方法と似ています.鍵は、2番目のパラメータapplyは1つの配列に入る必要があります.callはパラメータの一つを順番にbindに導入する必要があります.この2つの方法との違いは、appyとcallはいずれもすぐに関数を実行します.関数に結合されたthisを返します.新しい関数の目的は改造関数です.
5.thisの紛失問題
関数を別の関数のパラメータとする場合は、参照関数の問題です.
window.a='window';
function callback(){
    var a='leo';
    console.log(this.a)
}
function pay(callback){
    callback()
}
pay(callback)//window