JavaScript哪些場(chǎng)景不能使用箭頭函數(shù)
1. 定義對(duì)象方法
JS 中對(duì)象方法的定義方式是在對(duì)象上定義一個(gè)指向函數(shù)的屬性,當(dāng)方法被調(diào)用的時(shí)候,方法內(nèi)的 this 就會(huì)指向方法所屬的對(duì)象。
let obj = { array: [1, 2, 3], sum: () => { console.log(this === window); // true return this.array.reduce((result, item) => result + item); } }; console.log(this === window); //true obj.sum();//報(bào)錯(cuò):Uncaught TypeError: Cannot read property 'reduce' of undefined at Object.sum
運(yùn)行時(shí) this.array 是未定義的,調(diào)用 obj.sum 的時(shí)候,執(zhí)行上下文里面的 this 仍然指向的是 window,原因是箭頭函數(shù)把函數(shù)上下文綁定到了 window 上,this.array 等價(jià)于 window.array,顯然后者是未定義的。
修改方式:使用函數(shù)表達(dá)式或者方法簡(jiǎn)寫(xiě)(ES6 中已經(jīng)支持)來(lái)定義方法,這樣能確保 this 是在運(yùn)行時(shí)是由包含它的上下文決定的。代碼如下:
let obj = { array: [1, 2, 3], sum() { console.log(this === window); // false return this.array.reduce((result, item) => result + item); } }; console.log(this === window); //true console.log(obj.sum());//6
2.定義原型方法
同樣的規(guī)則適用于原型方法(prototype method)的定義,使用箭頭函數(shù)會(huì)導(dǎo)致運(yùn)行時(shí)的執(zhí)行上下文錯(cuò)誤。比如下面代碼:
function Cat(name) { this.name = name; } Cat.prototype.sayCatName = () => { console.log(this === window); // => true return this.name; }; const cat = new Cat('Tom'); console.log(cat.sayCatName()); // undefined
使用傳統(tǒng)的函數(shù)表達(dá)式就能解決問(wèn)題,代碼如下所示:
function Cat(name) { this.name = name; } Cat.prototype.sayCatName = function () { console.log(this === window); // => false return this.name; } const cat = new Cat('Tom'); console.log(cat.sayCatName()); // Tom
sayCatName 變成普通函數(shù)之后,被調(diào)用時(shí)的執(zhí)行上下文就會(huì)指向新創(chuàng)建的 cat 實(shí)例。
3. 定義事件回調(diào)函數(shù)
箭頭函數(shù)在聲明的時(shí)候就綁定了執(zhí)行上下文,要?jiǎng)討B(tài)改變上下文是不可能的,在需要?jiǎng)討B(tài)上下文的時(shí)候它的弊端就凸顯出來(lái)。
比如在客戶端編程中常見(jiàn)的 DOM 事件回調(diào)函數(shù)(event listenner)綁定,觸發(fā)回調(diào)函數(shù)時(shí) this 指向當(dāng)前發(fā)生事件的 DOM 節(jié)點(diǎn),而動(dòng)態(tài)上下文這個(gè)時(shí)候就非常有用,比如下面這段代碼試圖使用箭頭函數(shù)來(lái)作事件回調(diào)函數(shù)。
const button = document.getElementById('myButton'); button.addEventListener('click', () => { console.log(this === window); // true this.innerHTML = 'Clicked button'; });
在全局上下文下定義的箭頭函數(shù)執(zhí)行時(shí) this 會(huì)指向 window,當(dāng)單擊事件發(fā)生時(shí),this.innerHTML 就等價(jià)于 window.innerHTML,而后者是沒(méi)有任何意義的。
使用函數(shù)表達(dá)式就可以在運(yùn)行時(shí)動(dòng)態(tài)的改變 this,修正后的代碼:
const button = document.getElementById('myButton'); button.addEventListener('click', function () { console.log(this === button); // true this.innerHTML = 'Clicked button'; });
4. 定義構(gòu)造函數(shù)
構(gòu)造函數(shù)中的 this 指向新創(chuàng)建的對(duì)象,當(dāng)執(zhí)行 new Car() 的時(shí)候,構(gòu)造函數(shù) Car 的上下文就是新創(chuàng)建的對(duì)象,也就是說(shuō) this instanceof Car === true。顯然,箭頭函數(shù)是不能用來(lái)做構(gòu)造函數(shù), 實(shí)際上 JS 會(huì)禁止你這么做,如果你這么做了,它就會(huì)拋出異常。
比如下面的代碼就會(huì)報(bào)錯(cuò):
const Message = (text) => { this.text = text; }; const helloMessage = new Message('Hello World!');//報(bào)錯(cuò): Throws "TypeError: Message is not a constructor"
構(gòu)造新的 Message 實(shí)例時(shí),JS 引擎拋了錯(cuò)誤,因?yàn)?Message 不是構(gòu)造函數(shù)??梢酝ㄟ^(guò)使用函數(shù)表達(dá)式或者函數(shù)聲明來(lái)聲明構(gòu)造函數(shù)修復(fù)上面的例子。
const Message = function(text) { this.text = text; }; const helloMessage = new Message('Hello World!'); console.log(helloMessage.text); // 'Hello World!'
以上就是JavaScript哪些場(chǎng)景不能使用箭頭函數(shù)的詳細(xì)內(nèi)容,更多關(guān)于JavaScript不能使用箭頭函數(shù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
stream.js 一個(gè)很小、完全獨(dú)立的Javascript類庫(kù)
stream.js 是一個(gè)很小、完全獨(dú)立的Javascript類庫(kù),它為你提供了一個(gè)新的Javascript數(shù)據(jù)結(jié)構(gòu):streams2011-10-10通過(guò)js實(shí)現(xiàn)壓縮圖片上傳功能
這篇文章主要介紹了通過(guò)js實(shí)現(xiàn)壓縮圖片上傳功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02用js的document.write輸出的廣告無(wú)阻塞加載的方法
這篇文章主要介紹了用js的document.write輸出的廣告無(wú)阻塞加載的方法,需要的朋友可以參考下2014-06-06js中的scroll和offset 使用比較的實(shí)例與分析
這篇文章介紹了js中的scroll和offset使用比較的實(shí)例與分析,有需要的朋友可以參考一下2013-09-09js 數(shù)組 find,some,filter,reduce區(qū)別詳解
區(qū)分清楚Array中filter、find、some、reduce這幾個(gè)方法的區(qū)別,根據(jù)它們的使用場(chǎng)景更好的應(yīng)用在日常編碼中。具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06JavaScript設(shè)計(jì)模式之構(gòu)造器模式(生成器模式)定義與用法實(shí)例分析
這篇文章主要介紹了JavaScript設(shè)計(jì)模式之構(gòu)造器模式(生成器模式)定義與用法,結(jié)合實(shí)例形式分析了javascript構(gòu)造器模式的概念、原理、與工廠模式的區(qū)別以及相關(guān)使用方法,需要的朋友可以參考下2018-07-07JS實(shí)現(xiàn)斐波那契數(shù)列的五種方式(小結(jié))
這篇文章主要介紹了JS實(shí)現(xiàn)斐波那契數(shù)列的五種方式(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Javascript模塊化機(jī)制實(shí)現(xiàn)原理詳解
這篇文章主要介紹了Javascript模塊化機(jī)制實(shí)現(xiàn)原理詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04JavaScript定義函數(shù)_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了JavaScript定義函數(shù)的相關(guān)資料,需要的朋友可以參考下2017-06-06