寫在前面
在今天寫一段js代碼時,發現無論如何也得不到想到的效果,示例代碼如下:
$('#body tr').mouseover(() => {
let index=$(this).prevAll().length
myChart.dispatchAction({ type: 'highlight', name:formatData[index].name});
});
解釋一下,這里首先獲取了當前tr元素,然后去計算了之前有多少個tr元素從而准確的獲得當前tr的索引。最后針對索引的tr元素進行高亮處理。但我的index的值一直是0,即前面的元素一直是0,這顯然是不和常理的。
發現問題
當我死馬當做活馬醫的時候,輸出了$(this)對象。發現是一個Window對象。這就讓人費解了,按說這里的this應該是一個tr元素才對啊,於是我把lambda表達式換成了最基本的寫法:
$('#body tr').mouseover(function(){
let index=$(this).prevAll().length
myChart.dispatchAction({ type: 'highlight', name:formatData[index].name});
});
發現這樣就可以了。這么神奇的么,遂上網搜索了一下。
解釋問題
最后,翻閱了一些資料與文檔后,發現了這樣一句話:
內部類的聲明會創建一個新的命名作用域,在這個作用域中,this與super指的是內部類本身的當前實例;相反,lambda表達式並不會引入任何新的命名環境。這樣就避免了內部類名稱查找的復雜性,名稱查找會導致很多小錯誤,例如想要調用外圍實例方法時卻錯誤地調用了內部類實例的Object方法。
這就可以很好的解釋這里的this指向的問題了,lambda表達式不會引入內部類,所以這里的this指向的其實是外部,有的資料說是最近scope的對象,這也就是為什么在使用lambda表達式的時候輸出的是window對象了。
總結
總的來說,出現這種情況還是我自己對lambda表達式的理解不夠深刻,以后要加強對於js的理解了。