JavaScript中的this很容易讓人迷惑豁护,但弄清楚后其實還是很好區(qū)分的经备。JavaScript中的this總是指向一個對象拒秘,而具體指向哪個對象是在運行時基于函數(shù)的執(zhí)行環(huán)境動態(tài)綁定的皇钞,不是函數(shù)聲明時的環(huán)境。
實際能區(qū)分如下4種的情況就Ok了垛耳。
- 函數(shù)作為對象的屬性調(diào)用時
- 作為普通函數(shù)時
- 構(gòu)造器中
- Function.prototype.apply/call 時
下面來分別講講。
作為函數(shù)屬性被調(diào)用
當(dāng)函數(shù)作為對象的屬性(方法)被調(diào)用時飘千,this指向該對象
const obj = {
name: 'Asher',
getName: function () {
console.log(this === obj); // true
console.log(this.name); // 輸出Asher
}
}
obj.getName();
作為普通函數(shù)調(diào)用
當(dāng)函數(shù)不作為對象的屬性被調(diào)用時堂鲜,就是普通函數(shù)的方式,此時的this總是指向全局對象护奈。瀏覽器環(huán)境更里缔莲,這個全局對象就是window對象。
window.name = 'global asher';
const getName = function () {
console.log(this.name)
}
getName() // 輸出global asher
下面情況與第一種情況會讓人很迷惑
由于obj.getName方法被另外一個變量引用后再調(diào)用霉旗,此時已經(jīng)是做為普通函數(shù)調(diào)用了痴奏,故this指向的是windowwindow.name = 'global' const obj = { name: 'ahser', getName: function () { console.log(this.name); } } const getName = obj.getName; getName() // 輸出global
構(gòu)造器
當(dāng)函數(shù)使用new執(zhí)行是,函數(shù)是作為構(gòu)造器的厌秒,this指向的是生成的對象
const myClass = function () {
this.name = 'Asher';
}
const obj = new myClass();
console.log(obj.name) // 輸出Asher
apply & call 調(diào)用
這兩種調(diào)用方式就很靈活了读拆,可以動態(tài)的改變函數(shù)this的指向。
const obj1 = {
name: 'Asher',
getName: function () {
return this.name
}
}
const obj2 = {
name: 'Tan'
}
console.log(obj1.getName()) // output: Asher
console.log(obj1.getName.call(obj2)) // output: Tan
掌握了這四種情況的this指向简僧,就基本上完全理解了JavaScript的this了建椰,不會再被迷惑this指向的是哪個對象。