我們都知道在es6中函數(shù)的擴展多了箭頭函數(shù),那么箭頭函數(shù)中的this如何指向呢花墩?
下面我們來看一看:
其實es6的this指向就是一句話,this對象的指向是可變的盔性,但是在箭頭函數(shù)中仲锄,他是固定的劲妙。函數(shù)體內的this對象,就是定義時所在的對象儒喊,而不是使用時所在的對象
setTimeout的參數(shù)是一個箭頭函數(shù)镣奋,這個箭頭函數(shù)的定義生效是在foo函數(shù)生成時,而它的真正執(zhí)行要等到 100 毫秒后怀愧。如果是普通函數(shù)侨颈,執(zhí)行時this應該指向全局對象window,這時應該輸出21芯义。但是哈垢,箭頭函數(shù)導致this總是指向函數(shù)定義生效時所在的對象(本例是{id: 42}),所以輸出的是42扛拨。
箭頭函數(shù)可以讓setTimeout里面的this耘分,綁定定義時所在的作用域,而不是指向運行時所在的作用域绑警。下面是另一個例子求泰。
Timer函數(shù)內部設置了兩個定時器,分別使用了箭頭函數(shù)和普通函數(shù)计盒。前者的this綁定定義時所在的作用域(即Timer函數(shù))渴频,后者的this指向運行時所在的作用域(即全局對象)。所以北启,3100 毫秒之后枉氮,timer.s1被更新了 3 次,而timer.s2一次都沒更新暖庄。
箭頭函數(shù)可以讓this指向固定化聊替,這種特性很有利于封裝回調函數(shù)。下面是一個例子培廓,DOM 事件的回調函數(shù)封裝在一個對象里面惹悄。
上面代碼的init方法中,使用了箭頭函數(shù)肩钠,這導致這個箭頭函數(shù)里面的this泣港,總是指向handler對象。否則价匠,回調函數(shù)運行時当纱,this.doSomething這一行會報錯,因為此時this指向document對象踩窖。
this指向的固定化坡氯,并不是因為箭頭函數(shù)內部有綁定this的機制,實際原因是箭頭函數(shù)根本沒有自己的this,導致內部的this就是外層代碼塊的this箫柳。正是因為它沒有this手形,所以也就不能用作構造函數(shù)。
所以悯恍,箭頭函數(shù)轉成 ES5 的代碼如下
上面代碼之中库糠,只有一個this,就是函數(shù)foo的this涮毫,所以t1瞬欧、t2、t3都輸出同樣的結果罢防。因為所有的內層函數(shù)都是箭頭函數(shù)艘虎,都沒有自己的this,它們的this其實都是最外層foo函數(shù)的this篙梢。
除了this,以下三個變量在箭頭函數(shù)之中也是不存在的美旧,指向外層函數(shù)的對應變量:arguments渤滞、super、new.target榴嗅。
上面代碼中妄呕,箭頭函數(shù)內部的變量arguments,其實是函數(shù)foo的arguments變量嗽测。
另外绪励,由于箭頭函數(shù)沒有自己的this,所以當然也就不能用call()唠粥、apply()疏魏、bind()這些方法去改變this的指向。
上面代碼中晤愧,箭頭函數(shù)沒有自己的this大莫,所以bind方法無效,內部的this指向外部的this官份。
長期以來只厘,JavaScript 語言的this對象一直是一個令人頭痛的問題,在對象方法中使用this舅巷,必須非常小心羔味。箭頭函數(shù)”綁定”this,很大程度上解決了這個困擾钠右。
原文來自:阮一峰ECMAScript 6 入門