Day33-「this」好奇怪!
聽前輩說,「this」在JavaScript裡面是一個大坑。
前面有提過「this」在事件監聽中,不考慮事件冒泡的情況下,this就等同是e.target,但是如果是被事件冒泡觸發的this則為e.currentTarget。
現在來談談「this」在其他地方要注意的事情。
首先要記住這句話,只要理解這個原則,大部分遇到「this」的狀況都可以輕鬆掌握:
「this代表的是function執行時所屬的物件,而不是function本身」
「this」是在函式被呼叫的時候被自動生成的內部物件,this不等於function,隨著呼叫函示的物件不同,「this」所指向的值也不同。
沒有特別指定this的情況下,this預設綁定(Default Binding)「全域物件」,也就是window。
但在ES5的嚴格模式下,禁止this自動指定為全域物件,這點要特別注意。
所以在全域環境中直接呼叫monster()函式時,this.seven是指向全域變數的var seven = “江南七怪”;當monster()作為obj物件func屬性的方法的時候,this.seven會指向obj物件的seven屬性”七喜汽水”。
soda()透過this.call()來叫用call(),這時call()裡面的this.seven是指向全域變數的seven,所以得到的結果是”江南七怪”。
如何強制指定this
在JavaScript有三種方式可以強制指定this給function,這種方式也叫「顯式綁定」,分別是:
- .call()
- .apply()
- .bind()
先來說說.call與.apply
上面的程式碼式使用.call與.apply去呼叫執行funcA,第一個參數context為所帶入的物件,也就是強制用那個物件來當成function執行時的物件。
.call與.apply作用一樣,差別在.apply第一個參數(帶入的物件)之後的參數以陣列方式傳入,而.call則是使用逗號隔開。
我們可以看見this.name與this.wife綁定到帶入的物件上。而this隨著所帶入的物件不同,指向也會動態地改變。
而bind的用法如下:
藉由‵let kuoWife = funcA.bind(kuo) ‵也可以把this指向所帶入的物件。
其實以上的應用,萬變不離其宗,只要記得:「this代表的是function執行時所屬的物件,而不是function本身」