日常用this不少,對this的理解就是this是對應執行環境,然而不少時候效果並非想要的,最近看了一些談到this的筆記和書籍,總結下。數組
對this的誤解:app
this是指向函數自己函數
先上個demo吧this
1 var a =0; 2 demo.a=2; 3 function demo(){ 4 console.log('ok'); 5 this.a++ 6 } 7 demo();//ok 8 console.log(demo.a);//2 9 console.log(a); //1
上面的demo已經得知,若是this是指向函數自己,那麼demo.a的值應該爲3,但仍是2說明調用的不是demo函數。spa
window對象的a卻增長了,說明demo函數中的this是指向window(等會說爲何)code
this是在調用時被綁定的,取決於函數的調用位置(也就是調用方法):對象
1.默認綁定:blog
最經常使用也是函數調用類型,當只有一個獨立函數時,this指向的是window對象(解釋上面例子爲何console.log(a)會是1)。it
注意:當使用嚴格模式,this會綁定到undefinedio
2.隱式綁定
函數調用的位置有上下文環境(我理解爲對象調用模式,函數是一個對象的方法)
var obj1={
a:2,
demo:demo
};
var obj={
a:1,
obj1:obj1
};
function demo(){
console.log(this.a)
}
obj.obj1.demo()//2
當函數的執行環境是在obj對象,this指向的就是obj。若是被包裹了幾層對象,this只會綁定最後一層對象(上面demo中this最後綁定到obj1上)
注意:1.有時咱們不會寫這麼長一串obj.obj1.demo,而是賦給一個變量,還能達到咱們想要的效果嗎?
1 var a =0 2 var obj1={ 3 a:2, 4 demo:demo 5 }; 6 var obj={ 7 a:1, 8 obj1:obj1 9 }; 10 function demo(){ 11 console.log(this.a) 12 } 13 obj.obj1.demo(); //2 14 var fn= obj.obj1.demo; 15 fn(); //0 16 obj.dd = obj.obj1.demo; 17 obj.dd() //1
當我把obj.obj1.demo賦給fn時,再執行fn(),結果倒是0.why? 按照咱們上面說的,fn()能夠理解爲一個獨立函數(沒有任何修飾符),其中的this就是指向window,即a=0。
我以爲還能這麼理解,函數中this,取決於調用函數上一級(也就是上面說的最後一級)的對象。
如上:obj.dd = obj.obj1.demo,而後執行obj.dd(),結果是1,也就是說如今函數中你的this綁定的是obj對象。同理也能夠解釋fn()其實就是window.fn(),綁定的是window對象
3.顯示綁定
顯示綁定就是經過apply,call,bind,直接將函數中的this綁定到想要的對象上
仍是先看demo吧
1 var obj1={ 2 a:2, 3 demo:demo 4 }; 5 var obj={ 6 a:1, 7 obj1:obj1 8 }; 9 function demo(){ 10 console.log(this.a) 11 } 12 obj.obj1.demo(); //2 13 obj.obj1.demo.call(obj); //1 14 var fn= obj.obj1.demo.bind(obj); 15 fn() //1
簡單介紹下apply call bind。apply和call是函數內置的方法,第一個參數是指定函數執行環境,第二個參數是傳給函數的參數,call是將參數依次傳給函數,apply則是將參數組合在一個數組中,將數組傳給函數,
bind也是綁定指定執行環境,可是不會執行(使用call和apply的時,函數就執行了)
根據上面說的,正常obj.obj1.demo()獲得的結果是2,可是使用call後this綁定的obj上,因此a的值爲1.後面使用bind同理(只是函數沒有執行,須要執行一次)
4.構造函數模式
建立一個構造函數的實例,構造函數中的this會綁定到這個實例對象上
1 function Per(){ 2 this.a=1 3 } 4 var dd = new Per(); 5 alert(dd.a) //1
dd是Per的一個實例,this綁定在dd上,建立了dd的一個屬性a,且值爲1