剛接觸this時候,對於它的存在很問號,在想為什麼需要它?而且因為好多情況指向又不同,真的好頭暈
MDN也不是那麼好理解,拜讀了幾篇大大們的文章和翻書,以下理解如有錯誤還請告知~謝謝!
先來看MDN怎麼說:
Most typically, it is used in object methods, where this refers to the object that the method is attached to, thus allowing the same method to be reused on different objects.
this最常使用在物件的方法中,它會指向呼叫該方法的物件,
所以相同的方法就能夠在不同的物件上重複使用。
這句話先用範例來說明:
function showMessage(){
console.log(userA.message);
}
const userA = {
message:"userA message",
showMessage:showMessage
}
const userB = {
message:"userB message",
showMessage:showMessage
}
在userA和userB都加上showMessage的方法,兩個物件都呼叫此方法,但因為showMessage函式回傳值userA.message
寫死了,所以兩個物件呼叫結果都會得到"userA message"
。
執行結果:
userA.showMessage(); //"userA message"
userB.showMessage(); //"userA message"
MDN說:「使用this它會指向呼叫該方法的物件」,接下來把剛剛showMessage函式內修改成有this:
function showMessage(){
console.log(this.message); //這邊改成this.message
}
const userA = {
message:"userA message",
showMessage:showMessage
}
const userB = {
message:"userB message",
showMessage:showMessage
}
執行結果:
userA.showMessage(); //"userA message"
userB.showMessage(); //"userB message"
this會指向當前的物件而有不同的結果。這也就是MDN上說的:「相同的方法就能夠在不同的物件上重複使用。」
函式作為物件的方法呼叫,也就是userA.showMessage()方法的this,會指向userA物件,所以this.message的值會是"userA message"
。
如果用變數指向函式來呼叫呢?
var message = "global message";
function showMessage(){
console.log(this.message);
}
const userA = {
message:"userA message",
showMessage:showMessage
}
const getMessage = userA.showMessage;
getMessage(); //global message
為什麼getMessage最後結果得到是 "global message"
而不是 "userA message"
?
因為getMessage變數只是建立相同函式的參照,並沒有綁定userA作為this。
記得剛剛規範說的,this的值取決於函式呼叫的方式。所以getMessage()就只是一般函式呼叫,this就會指向全域window物件。
小提醒:
用var宣告的變數,會視為window物件的一個屬性,也就是 window.message = "global message"
,如圖:
所以showMessage函式印出會是"global message"
。
但是,用let宣告的變數,不會變成window物件的屬性!所以結果會是undefined,因為let為區塊作用域。
this會根據函式的呼叫方式動態綁定this的值,而且只有函式執行時,會自動產生this,其他型別例如:字串、數值、布林值、陣列、物件等本身不會自動產生this。
以上是this的小概念,下篇分享如何綁定this以及箭頭函式的this,謝謝!
MDN - this
Chris 技術筆記-this 決策演算法 - 什麼是 this
What's THIS in JavaScript ? [上][中][下]
JS 原力覺醒 Day17 - this 的四種繫結
淺談 JavaScript 頭號難題 this:絕對不完整,但保證好懂
JavaScript 忍者秘籍, 2/e (Secrets of the JavaScript Ninja, 2/e)