編寫(xiě)高質(zhì)量箭頭函數(shù)的5個(gè)優(yōu)秀做法
箭頭功能值得流行。它的語(yǔ)法簡(jiǎn)潔明了,使用詞法綁定綁定 this,它非常適合作為回調(diào)。在本文中,通過(guò)了解決學(xué)習(xí)5個(gè)優(yōu)秀實(shí)踐,以便我們可以從中學(xué)習(xí)更多箭頭函數(shù)的知識(shí),并從它身上獲得更多的好處。
1. 箭頭函數(shù)名推斷
JS 中的箭頭函數(shù)是匿名(anonymous)的:函數(shù)的name屬性是''。
- (number=>number+1).name;//=>''
在調(diào)試會(huì)話或調(diào)用堆棧分析期間,匿名函數(shù)被標(biāo)記為anonymous。不幸的是,anonymous程序不提供有關(guān)正在執(zhí)行的代碼的任何線索。
這里是執(zhí)行匿名函數(shù)的代碼的調(diào)試會(huì)話:

右邊的調(diào)用堆棧由兩個(gè)標(biāo)記為anonymous的函數(shù)組成,我們無(wú)法從這樣的調(diào)用堆棧信息中獲得任何有用的信息。
幸運(yùn)的是,函數(shù)名推斷(ES2015的功能)可以在某些條件下檢測(cè)到函數(shù)名稱。名稱推斷的思想是JS 可以從其語(yǔ)法位置確定箭頭函數(shù)名稱:從保存函數(shù)對(duì)象的變量名稱中獲取。
我們來(lái)看看函數(shù)名稱推斷的工作原理:
- constincreaseNumber=number=>number+1;increaseNumber.name;//=>'increaseNumber'
因?yàn)樽兞縤ncreaseNumber保存了箭頭函數(shù),所以 JS 決定使用increaseNumber作為該函數(shù)的名稱。因此,箭頭函數(shù)的名稱為 'increaseNumber'。
第1個(gè)實(shí)踐:
一個(gè)好的做法是使用函數(shù)名稱推斷來(lái)命名箭頭函數(shù)。
現(xiàn)在我們用使用名稱推斷的代碼檢查一個(gè)調(diào)試會(huì)話:

因?yàn)榧^函數(shù)有名稱,所以調(diào)用堆棧提供了有關(guān)正在執(zhí)行的代碼的更多信息。
- handleButtonClick函數(shù)名稱表示發(fā)生了單擊事件
- gainCounter增加一個(gè)計(jì)數(shù)器變量。
2.盡可能使用內(nèi)聯(lián)方式
內(nèi)聯(lián)函數(shù)是僅具有一個(gè)表達(dá)式的函數(shù)。我喜歡箭頭功能,可以編寫(xiě)短內(nèi)聯(lián)函數(shù)。
例如,不要使用箭頭函數(shù)的長(zhǎng)形式:
- constarray=[1,2,3];array.map((number)=>{returnnumber*2;});
當(dāng)箭頭函數(shù)只有一個(gè)表達(dá)式時(shí),可以輕松地刪除大括號(hào){}和return語(yǔ)句:
- constarray=[1,2,3];array.map(number=>number*2);
第2個(gè)實(shí)踐:
當(dāng)函數(shù)只有一個(gè)表達(dá)式時(shí),一個(gè)好的做法是使用內(nèi)聯(lián)箭頭函數(shù)格式
3.胖箭頭和比較運(yùn)算符
比較操作符>、<、<=和>=看起來(lái)類似于f胖箭頭=>(它定義了箭頭函數(shù))。當(dāng)在內(nèi)聯(lián)箭頭函數(shù)中使用這些比較操作符時(shí),會(huì)產(chǎn)生一些混淆。
例如我們定義一個(gè)使用<=操作符的箭頭函數(shù)
- constnegativeToZero=number=>number<=0?0:number;
同一行上的兩個(gè)符號(hào)=>和<=的存在會(huì)引起誤解。
為了清楚地將胖箭頭與比較操作符區(qū)分開(kāi),我們可以使用圓括號(hào):
- constnegativeToZero=number=>(number<=0?0:number);
第二個(gè)選項(xiàng)是使用更長(zhǎng)的形式來(lái)定義箭頭函數(shù):
- constnegativeToZero=number=>{returnnumber<=0?0:number;};
這些重構(gòu)消除了胖箭頭符號(hào)和比較操作符之間的混淆。
第3個(gè)實(shí)踐:
如果箭頭函數(shù)包含操作符>、<、<=和>=,一個(gè)好的做法是將表達(dá)式包裝成一對(duì)括號(hào),或者故意使用更長(zhǎng)的箭頭函數(shù)形式。
4.構(gòu)造普通對(duì)象
在內(nèi)聯(lián)箭頭函數(shù)中使用對(duì)象字面量會(huì)觸發(fā)語(yǔ)法錯(cuò)誤:
- constarray=[1,2,3];//throwsSyntaxError!array.map(number=>{'number':number});
JS 認(rèn)為花括號(hào)是代碼塊,而不是對(duì)象文字。
將對(duì)象字面量加上一對(duì)括號(hào)即可解決此問(wèn)題:
- constarray=[1,2,3];//Works!array.map(number=>({'number':number}));
如果對(duì)象字面量有很多屬性,我們可以使用換行,同時(shí)仍然保持箭頭函數(shù)內(nèi)聯(lián)
- constarray=[1,2,3];//Works!array.map(number=>({'number':number'propA':'valueA','propB':'valueB'}));
第4個(gè)實(shí)踐:
在內(nèi)聯(lián)箭頭函數(shù)中使用對(duì)象時(shí),把改對(duì)象包裝在一對(duì)括號(hào)中。
5.注意過(guò)多的嵌套
箭頭函數(shù)的語(yǔ)法很短,很好。但是,副作用是,當(dāng)許多箭頭函數(shù)嵌套時(shí),它可能是晦澀難懂。
我們考慮以下情況。單擊按鈕后,啟動(dòng)對(duì)服務(wù)器的請(qǐng)求,響應(yīng)準(zhǔn)備就緒后,將各項(xiàng)記錄到控制臺(tái):
- myButton.addEventListener('click',()=>{fetch('/items.json').then(response=>response.json());.then(json=>{json.forEach(item=>{console.log(item.name);});});});
這里有三層箭頭函數(shù)的嵌套,需要花時(shí)間和精力來(lái)了解代碼的作用。
為了提高嵌套函數(shù)的可讀性,第一種方法是引入每個(gè)包含箭頭函數(shù)的變量,該變量應(yīng)簡(jiǎn)明地描述函數(shù)的功能。
- constreadItemsJson=json=>{json.forEach(item=>console.log(item.name));};consthandleButtonClick=()=>{fetch('/items.json').then(response=>response.json());.then(readItemsJson);};myButton.addEventListener('click',handleButtonClick);
重構(gòu)將箭頭函數(shù)提取到變量readItemsJson和handleButtonClick中。嵌套級(jí)別從3減少到2?,F(xiàn)在,我們可以更輕松地了解腳本的功能。
更好的是,可以使用async/await語(yǔ)法重構(gòu)整個(gè)函數(shù),這是解決函數(shù)嵌套的一個(gè)很好的方法:
- consthandleButtonClick=async()=>{constresponse=awaitfetch('/items.json');constjson=awaitresponse.json();json.forEach(item=>console.log(item.name));};myButton.addEventListener('click',handleButtonClick);
第5個(gè)實(shí)踐:
避免箭頭函數(shù)過(guò)多的嵌套,好的做法是通過(guò)將箭頭函數(shù)提取為獨(dú)立函數(shù),或者盡可能使用async/await語(yǔ)法。
6. 總結(jié)
JS中的箭頭函數(shù)是匿名的。為了使調(diào)試更高效,一個(gè)好的實(shí)踐是使用變量來(lái)保存箭頭函數(shù),這允許JS 推斷函數(shù)名。
當(dāng)函數(shù)主體具有一個(gè)表達(dá)式時(shí),嵌入式箭頭函數(shù)非常方便。
操作符>、<、<=和>=看起來(lái)類似于胖箭頭=>,在內(nèi)聯(lián)箭頭函數(shù)中使用這些操作符時(shí)必須小心。
對(duì)象字面量語(yǔ)法{prop:'value'}與代碼塊{}相似。因此,當(dāng)將對(duì)象字面量放置在嵌入式箭頭函數(shù)中時(shí),需要將其包裝在一對(duì)括號(hào)中:()=>({prop:'value'})。
最后,函數(shù)的過(guò)度嵌套模糊了代碼意圖。減少箭頭函數(shù)嵌套的一個(gè)好方法是將它們提取到變量中?;蛘撸瑖L試使用更好的特性,如async/await語(yǔ)法。