JavaScript哪些場景不能使用箭頭函數(shù)
1. 定義對象方法
JS 中對象方法的定義方式是在對象上定義一個指向函數(shù)的屬性,當(dāng)方法被調(diào)用的時(shí)候,方法內(nèi)的 this 就會指向方法所屬的對象。
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)錯: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á)式或者方法簡寫(ES6 中已經(jīng)支持)來定義方法,這樣能確保 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ù)會導(dǎo)致運(yùn)行時(shí)的執(zhí)行上下文錯誤。比如下面代碼:
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á)式就能解決問題,代碼如下所示:
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í)行上下文就會指向新創(chuàng)建的 cat 實(shí)例。
3. 定義事件回調(diào)函數(shù)
箭頭函數(shù)在聲明的時(shí)候就綁定了執(zhí)行上下文,要動態(tài)改變上下文是不可能的,在需要動態(tài)上下文的時(shí)候它的弊端就凸顯出來。
比如在客戶端編程中常見的 DOM 事件回調(diào)函數(shù)(event listenner)綁定,觸發(fā)回調(diào)函數(shù)時(shí) this 指向當(dāng)前發(fā)生事件的 DOM 節(jié)點(diǎn),而動態(tài)上下文這個時(shí)候就非常有用,比如下面這段代碼試圖使用箭頭函數(shù)來作事件回調(diào)函數(shù)。
const button = document.getElementById('myButton'); button.addEventListener('click', () => { console.log(this === window); // true this.innerHTML = 'Clicked button'; });
在全局上下文下定義的箭頭函數(shù)執(zhí)行時(shí) this 會指向 window,當(dāng)單擊事件發(fā)生時(shí),this.innerHTML 就等價(jià)于 window.innerHTML,而后者是沒有任何意義的。
使用函數(shù)表達(dá)式就可以在運(yùn)行時(shí)動態(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)建的對象,當(dāng)執(zhí)行 new Car() 的時(shí)候,構(gòu)造函數(shù) Car 的上下文就是新創(chuàng)建的對象,也就是說 this instanceof Car === true。顯然,箭頭函數(shù)是不能用來做構(gòu)造函數(shù), 實(shí)際上 JS 會禁止你這么做,如果你這么做了,它就會拋出異常。
比如下面的代碼就會報(bào)錯:
const Message = (text) => { this.text = text; }; const helloMessage = new Message('Hello World!');//報(bào)錯: Throws "TypeError: Message is not a constructor"
構(gòu)造新的 Message 實(shí)例時(shí),JS 引擎拋了錯誤,因?yàn)?Message 不是構(gòu)造函數(shù)??梢酝ㄟ^使用函數(shù)表達(dá)式或者函數(shù)聲明來聲明構(gòu)造函數(shù)修復(fù)上面的例子。
const Message = function(text) { this.text = text; }; const helloMessage = new Message('Hello World!'); console.log(helloMessage.text); // 'Hello World!'
以上就是JavaScript哪些場景不能使用箭頭函數(shù)的詳細(xì)內(nèi)容,更多關(guān)于JavaScript不能使用箭頭函數(shù)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
stream.js 一個很小、完全獨(dú)立的Javascript類庫
stream.js 是一個很小、完全獨(dú)立的Javascript類庫,它為你提供了一個新的Javascript數(shù)據(jù)結(jié)構(gòu):streams2011-10-10用js的document.write輸出的廣告無阻塞加載的方法
這篇文章主要介紹了用js的document.write輸出的廣告無阻塞加載的方法,需要的朋友可以參考下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這幾個方法的區(qū)別,根據(jù)它們的使用場景更好的應(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é)),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Javascript模塊化機(jī)制實(shí)現(xiàn)原理詳解
這篇文章主要介紹了Javascript模塊化機(jī)制實(shí)現(xiàn)原理詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04JavaScript定義函數(shù)_動力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了JavaScript定義函數(shù)的相關(guān)資料,需要的朋友可以參考下2017-06-06