JavaScript哪些場(chǎng)景不能使用箭頭函數(shù)
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); // truereturn this.array.reduce((result, item) => result + item); }};console.log(this === window); //trueobj.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); // falsereturn this.array.reduce((result, item) => result + item); }};console.log(this === window); //trueconsole.log(obj.sum());//62.定義原型方法
同樣的規(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)。
比如在客戶(hù)端編程中常見(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)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. 讀大數(shù)據(jù)量的XML文件的讀取問(wèn)題2. ASP刪除img標(biāo)簽的style屬性只保留src的正則函數(shù)3. 利用CSS3新特性創(chuàng)建透明邊框三角4. 解析原生JS getComputedStyle5. css代碼優(yōu)化的12個(gè)技巧6. ASP實(shí)現(xiàn)加法驗(yàn)證碼7. 無(wú)線標(biāo)記語(yǔ)言(WML)基礎(chǔ)之WMLScript 基礎(chǔ)第1/2頁(yè)8. PHP循環(huán)與分支知識(shí)點(diǎn)梳理9. ASP基礎(chǔ)入門(mén)第三篇(ASP腳本基礎(chǔ))10. JSP+Servlet實(shí)現(xiàn)文件上傳到服務(wù)器功能
