Js中的this總是指向一個對象,而具體指向哪一個對象是在運行時基于函數(shù)的執(zhí)行環(huán)境動態(tài)綁定的寥茫,而非函數(shù)被聲明時的環(huán)境遣蚀。
this的指向大致可以分為以下4種。
- 作為對象的方法調(diào)用(當(dāng)函數(shù)作為對象的方法被調(diào)用時纱耻,this指向該對象)
const obj = {
a: 1,
getA: () => {
console.log(this === obj); // true
console.log(this.a === 1); // true
},
};
obj.getA();
- 作為普通函數(shù)調(diào)用
當(dāng)函數(shù)不作為對象的屬性被調(diào)用時芭梯,也就是我們常說的普通函數(shù)方式,此時的this總是指向全局對象弄喘。在瀏覽器的Js中玖喘,這個全局對象是window對象。
window.name = 'globalName';
const getName = () => console.log(this.name);
getName(); // 輸出globalName
- 構(gòu)造器調(diào)用
Js中沒有類蘑志,但是可以從構(gòu)造函數(shù)中創(chuàng)造對象芒涡,同時也提供了new運算符,使得構(gòu)造器看起來更像一個類卖漫。
除了宿主提供的一些內(nèi)置函數(shù)费尽,大部分Js函數(shù)都可以當(dāng)做構(gòu)造器使用。構(gòu)造器的外表跟普通函數(shù)一模一樣羊始,它們的區(qū)別在于被調(diào)用的方式旱幼。當(dāng)用new運算符調(diào)用函數(shù)時,該函數(shù)總會返回一個對象突委,通常情況下柏卤,構(gòu)造器里的this就指向返回的這個對象。
const myClass = () => {
this.name = 'yuehun';
};
const obj = new myClass();
console.log(obj.name); // 輸出yuehun
但當(dāng)用new調(diào)用構(gòu)造器時匀油,還要注意一個問題缘缚,如果構(gòu)造器顯式地返回了一個object類型的對象,那么此次運算結(jié)果最終會返回這個對象敌蚜,而不是我們之前期待的this桥滨。
const myClass = {
this.name = 'john';
return {
name: 'yuehun',
};
};
const obj = new myClass();
console.log(obj.name); // 輸出yuehun
如果構(gòu)造器不顯式地返回任何數(shù)據(jù),或者是返回一個非對象類型的數(shù)據(jù),就不會造成上述問題
const myClass = () => {
this.name = 'yuehun';
return 'john';
};
const obj = new myClass();
console.log(obj.name); // 輸出yuehun
- Function.prototype.call或Function.prototype.apply調(diào)用
跟普通的函數(shù)相比齐媒,用這兩種方式能動態(tài)地改變傳入函數(shù)的this
const obj1 = {
name: 'john',
getName: () => this.name,
};
const obj2 = {
name: 'yuehun',
};
console.log(obj1.getName()); // 輸出john
console.log(obj1.getName.call(obj2)); // 輸出yuehun