標籤:undefined pre 返回 賦值 構造 foo 報錯 兩種 建構函式
作為JS中比較容易讓人迷糊,同時又很重要的痛點。
關於this指向問題,我們始終要記住一句話,這句話對於理解this指向很重要。這句話是:this要在執行時才能確認它的值,定義時無法確認。
this的指向出現在以下問題中,我根據我的理解在此做個總結。
1.全域中的this。很容易理解,在瀏覽器中,this指向window。
console.log(this) //window
2.作為普通函數執行的this。在瀏覽器中,this指向window。
var a=1;function foo(){ console.log(this); console.log(this.a);}foo(); //window 1
3.作為對象方法的函數的this。this指向定義該函數的對象。
var o={ a:1, foo:function(){console.log(this);console.log(this.a);} }o.foo(); // {a:1,foo:f} 1
但是要注意兩種情況
1.當把該對象的方法賦值給一個變數時,此時this的綁定會中斷,也就是說此時該變數聲明的函數變成了一個普通函數。this指向window
var o={ a:1, foo:function(){console.log(this);console.log(this.a);} }var goo=o.foo;//此時this的綁定中斷,不再指向對象ogoo(); // window undefined
2.當在該對象方法中在此定義一個方法,此時this仍然指向window。可能說的有點模糊,看下面代碼
var o={ a:1, foo:function(){ function f(){ console.log(this);console.log(this.a); }; f();//該函數雖然在foo中定義,但是是作為一個普通函數,而不是作為對象上的直接方法 } }o.foo();// window undefined
4.作為對象原型鏈上的this。this會指向該執行個體對象。
var o={ f:function(){ console.log(this.a+this.b);} }var p=Object.create(o);//該方法建立以o為原型的執行個體對象pp.a=1;p.b=2;p.f(); // 3
5.作為new構造器中的this,this會指向建立出來的執行個體對象。但是想更好的理解這一點,我們需要知道new的構造過程
new過程:
1.建立一個新對象
2.讓this指向該對象
3.執行該建構函式中的代碼,對this賦值
4.return this對象
但是要注意,若無return 或者 return基本類型值,建構函式返回this。若return一個其他對象的話,則return該對象,this指向該對象。看下面代碼
function M(){ this.a=10; }var o=new M();console.log(o.a); //10function N(){ this.a=20; return {a:30};} var p=new N();console.log(p.a);//30 這裡不是20,因為建構函式返回了一個對象
6.關於call,apply,bind中的this。這裡call和apply很相似,它們只是傳入參數的形式不一樣,所以只說call和bind。它們都可以改變this的指向。
var a=10;function f(){ console.log(this.a);}var p={a:30};f();//10 this指向windowf.call(p);// 30 this指向傳入的對象pf.call(null)// 10 this指向window 但是要注意在strict 模式下會報錯f.bind(p)// 沒有任何反應f.bind(p)();// 30//這是因為call是立即調用 而bind只是先改變this的指向,而沒有調用該函數
以上就是我總結出來的關於this指向的問題。因為是小白,理解上可能有些地方不是很恰當,總結的也可能不太全面。若發現問題,希望大家能夠及時指正錯誤,多多與我交流,共同進步。
JS之this