this指針的用法
常規用法
對this的理解是,指向 直接操作這個量的函數(或變量、對象)所屬的對象 的指針,也就是指向爹的爹,指向爺爺。通過幾個例子瞭解一下this的常見用法:
var name = 1;
var util = {
name: 2,
myName: this.name
getName: function(){
return this.name;
},
sub: {
name: 3,
getName: function(){
console.log(this);
return this.name
}
}
}
常規的this使用及結果
console.log(util.myName); //1 this指向window
console.log(util.getName()); // 2 this指向util
console.log(util.sub.getName()); // 3 this指向sub
如果是下列情況
var a = util.getName;
console.log(a()); //結果爲1
解釋:a=util.getName;
使得 a 成爲一個全局函數,即
a=function(){return this.name;}
此時的this指向 window ,得到 window.name
另一種情況:
var b = util.sub;
console.log(b.getName()); // 3
解釋:同理上個例子, b 是一個全局對象,
b = {
name: 3,
getName: function(){
console.log(this);
return this.name
}
b.getName()
中的this即指向getName()所屬的對象 b ,得到 b.name
還有,如果返回值是一個對象,那麼this指向的就是那個返回的對象,如果返回值不是一個對象那麼this還是指向函數的實例。例子如下:
function getName(){
this.name = 1;
return {}; // 返回對象
}
var a = new getName;
console.log(a.name); //undefined
function getName(){
this.name = 1;
return 2; // 返回非對象
}
var d = new getName;
console.log(d.name); //1
匿名函數中的this
在非嚴格模式下,匿名函數的執行環境具有全局性,因此其this對象指向window.
例子如下:
var obj = {
birth: 1990,
getAge: function () {
var b = this.birth; // 1990
var fn = function () {
return new Date().getFullYear() - this.birth; // this指向window(非嚴格模式)或undefined(嚴格模式)
};
return fn();
}
};
要想獲得預期的結果,可以使用以下hack寫法,加一行 var that = this;
var obj = {
birth: 1990,
getAge: function () {
var b = this.birth; // 1990
var fn = function () {
var that = this;
return new Date().getFullYear() - that.birth; // that指向obj
};
return fn();
}
};
箭頭函數中的this
箭頭函數和匿名函數的區別:箭頭函數內部的this是詞法作用域,由上下文確定。
回顧前面的例子,由於JavaScript函數對this綁定的錯誤處理,無法得到預期的結果。
現在,箭頭函數完全修復了this的指向,this總是指向詞法作用域,也就是外層調用者obj:
var obj = {
birth: 1990,
getAge: function () {
var b = this.birth; // 1990
var fn = () => new Date().getFullYear() - this.birth; // this指向obj對象
return fn();
}
};
obj.getAge(); // 25
如果使用箭頭函數,以前的那種hack寫法:
var that = this;
就不再需要了。
由於this在箭頭函數中已經按照詞法作用域綁定了,所以,用call()或者apply()調用箭頭函數時,無法對this進行綁定,即傳入的第一個參數被忽略:
var obj = {
birth: 1990,
getAge: function (year) {
var b = this.birth; // 1990
var fn = (y) => y - this.birth; // this.birth仍是1990
return fn.call({birth:2000}, year);
}
};
obj.getAge(2015); // 25