在網上看到很多關於箭頭函數this指向的博客和問題解答,但是基本寫的都不準確,有的甚至是錯誤的,在其他博客網站得到的答案基本就是“箭頭函數在定義時this指向誰那麼之後就一直指向誰”,這句話雖然不錯,但是這不還是沒說清楚到底是指向了誰嘛。實在看不下去了,今天在這裏詳細寫一寫箭頭函數的this到底指向誰?
在這裏首先看一看MDN對於箭頭函數的介紹:
箭頭函數表達式的語法比函數表達式更簡潔,並且沒有自己的this,arguments,super或new.target。箭頭函數表達式更適用於那些本來需要匿名函數的地方,並且它不能用作構造函數。
*其實箭頭函數根本沒有自己的this,更別談this的指向問題了。箭頭函數不光沒有this,而且連arguments、super、new.target也沒有。
箭頭函數中出現的this實際爲它所在上下文中的this,我們通過下面的例子來看一下:
案例1:
普通函數的this:
<button id="btn">按鈕</button>
<script>
document.getElementById("btn").onclick = function(){
console.log(this); // this指向當前發生事件的元素
}
</script>
輸出爲:
<button id="btn">按鈕</button>
箭頭函數:
<button id="btn">按鈕</button>
<script>
document.getElementById("btn").onclick = () => {
console.log(this);
}
</script>
輸出爲:
> Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, ...}
我們可以看到,在普通函數中我們點擊按鈕時觸發點擊事件,輸出的this
指向當前發生事件的元素也就是<button>
元素,箭頭函數中this
指向的是Window
,寫到這個地方其他的博客就得出了箭頭函數this
都指向Window
的錯誤結論!
案例2:
我們繼續看下面這個例子:
<button id="btn">按鈕</button>
<script>
var obj = {a:1,b:2};
function foo(){
document.getElementById("btn").onclick = () => {
console.log(this);
}
}
foo.call(obj);
</script>
我們在這個例子中,我們把foo()
函數的this
指向使用過call()
改爲了指向obj
,當我們點擊按鈕時得到輸出:
> {a: 1, b: 2}
咦?咱們的this
是在箭頭函數裏輸出的啊,爲啥指向了obj
呢?
上邊我們說了,箭頭函數其實是沒有自己的this
的,這個this
雖然在箭頭函數內,實際上這個this
的指向是foo()
的this
的指向(但不是foo的this,foo的this可以改變指向箭頭函數的不可以),所以我們可以看到它指向了obj
。
找指向的小技巧
找指向的小技巧就是扒皮,對!就是把箭頭函數這層皮扒掉,然後再看this
指向誰就是指向誰。
如下圖所示,我們將紅圈圈這層皮扒掉,再來看這個this
,此時我們可以看到指向的實際上是foo()this
的指向,也就是指向obj
。