作者:Dmitri Pavlutin
譯者:前端小智
來源:dmitripavlutin.com
點贊再看,養成習慣
本文
GitHub
github.com/qq449245884… 上已經收錄,更多往期高贊文章的分類,也整理了很多我的文件,和教程資料。歡迎Star和完善,大家面試可以參照考點複習,希望我們一起有點東西。
箭頭功能值得流行。 它的語法簡潔明瞭,使用詞法繫結繫結 this,它非常適合作為回撥。在本文中,通過了解決學習5個最佳實踐,以便我們可以從中學習更多箭頭函式的知識,並從它身上獲得更多的好處。
1. 箭頭函式名推斷
JS 中的箭頭函式是匿名(anonymous)
的:函式的name
屬性是''
。
( number => number + 1 ).name; // => ''
複製程式碼
在除錯會話或呼叫堆疊分析期間,匿名函式被標記為anonymous
。 不幸的是,anonymous
程式不提供有關正在執行的程式碼的任何線索。
這裡是執行匿名函式的程式碼的除錯會話:
右邊的呼叫堆疊由兩個標記為anonymous
的函式組成,我們無法從這樣的呼叫堆疊資訊中獲得任何有用的資訊。
幸運的是,函式名推斷(ES2015的功能)可以在某些條件下檢測到函式名稱。 名稱推斷的思想是JS 可以從其語法位置確定箭頭函式名稱: 從儲存函式物件的變數名稱中獲取。
我們來看看函式名稱推斷的工作原理:
const increaseNumber = number => number + 1;
increaseNumber.name; // => 'increaseNumber'
複製程式碼
因為變數increaseNumber
儲存了箭頭函式,所以 JS 決定使用increaseNumber
作為該函式的名稱。因此,箭頭函式的名稱為 'increaseNumber'
。
第1個實踐:
一個好的做法是使用函式名稱推斷來命名箭頭函式。
現在我們用使用名稱推斷的程式碼檢查一個除錯會話:
因為箭頭函式有名稱,所以呼叫堆疊提供了有關正在執行的程式碼的更多資訊。
-
handleButtonClick
函式名稱表示發生了單擊事件 -
gainCounter
增加一個計數器變數。
2.儘可能使用內聯方式
行內函數是僅具有一個表示式的函式。 我喜歡箭頭功能,可以編寫短行內函數。
例如,不要使用箭頭函式的長形式:
const array = [1, 2, 3];
array.map((number) => {
return number * 2;
});
複製程式碼
當箭頭函式只有一個表示式時,可以輕鬆地刪除大括號{}
和return
語句:
const array = [1, 2, 3];
array.map(number => number * 2);
複製程式碼
第2個實踐:
當函式只有一個表示式時,一個好的做法是使用內聯箭頭函式格式
3.胖箭頭和比較運算子
比較操作符>
、<
、<=
和>=
看起來類似於f胖箭頭=>
(它定義了箭頭函式)。當在內聯箭頭函式中使用這些比較操作符時,會產生一些混淆。
例如我們定義一個使用<=
操作符的箭頭函式
const negativeToZero = number => number <= 0 ? 0 : number;
複製程式碼
同一行上的兩個符號=>
和<=
的存在會引起誤解。
為了清楚地將胖箭頭與比較操作符區分開,我們可以使用圓括號:
const negativeToZero = number => (number <= 0 ? 0 : number);
複製程式碼
第二個選項是使用更長的形式來定義箭頭函式:
const negativeToZero = number => {
return number <= 0 ? 0 : number;
};
複製程式碼
這些重構消除了胖箭頭符號和比較操作符之間的混淆。
第3個實踐:
如果箭頭函式包含操作符
>
、<
、<=
和>=
,一個好的做法是將表示式包裝成一對括號,或者故意使用更長的箭頭函式形式。
4.構造普通物件
在內聯箭頭函式中使用物件字面量會觸發語法錯誤:
const array = [1, 2, 3];
// throws SyntaxError!
array.map(number => { 'number': number });
複製程式碼
JS 認為花括號是程式碼塊,而不是物件文字。
將物件字面量加上一對括號即可解決此問題:
const array = [1, 2, 3];
// Works!
array.map(number => ({ 'number': number }));
複製程式碼
如果物件字面量有很多屬性,我們可以使用換行,同時仍然保持箭頭函式內聯
const array = [1, 2, 3];
// Works!
array.map(number => ({
'number': number
'propA': 'value A',
'propB': 'value B'
}));
複製程式碼
第4個實踐:
在內聯箭頭函式中使用物件時,把改物件包裝在一對括號中。
5.注意過多的巢狀
箭頭函式的語法很短,很好。 但是,副作用是,當許多箭頭函式巢狀時,它可能是晦澀難懂。
我們考慮以下情況。 單擊按鈕後,啟動對伺服器的請求,響應準備就緒後,將各項記錄到控制檯:
myButton.addEventListener('click', () => {
fetch('/items.json')
.then(response => response.json());
.then(json => {
json.forEach(item => {
console.log(item.name);
});
});
});
複製程式碼
這裡有三層箭頭函式的巢狀,需要花時間和精力來了解程式碼的作用。
為了提高巢狀函式的可讀性,第一種方法是引入每個包含箭頭函式的變數,該變數應簡明地描述函式的功能。
const readItemsJson = json => {
json.forEach(item => console.log(item.name));
};
const handleButtonClick = () => {
fetch('/items.json')
.then(response => response.json());
.then(readItemsJson);
};
myButton.addEventListener('click', handleButtonClick);
複製程式碼
重構將箭頭函式提取到變數readItemsJson
和handleButtonClick
中。 巢狀級別從3減少到2。現在,我們可以更輕鬆地瞭解指令碼的功能。
更好的是,可以使用async/await
語法重構整個函式,這是解決函式巢狀的一個很好的方法:
const handleButtonClick = async () => {
const response = await fetch('/items.json');
const json = await response.json();
json.forEach(item => console.log(item.name));
};
myButton.addEventListener('click', handleButtonClick);
複製程式碼
第5個實踐:
避免箭頭函式過多的巢狀,好的做法是通過將箭頭函式提取為獨立函式,或者儘可能使用
async/await
語法。
6. 總結
JS中的箭頭函式是匿名的。為了使除錯更高效,一個好的實踐是使用變數來儲存箭頭函式,這允許JS 推斷函式名。
當函式主體具有一個表示式時,嵌入式箭頭函式非常方便。
操作符>
、<
、<=
和>=看起來類似於胖箭頭=>
,在內聯箭頭函式中使用這些操作符時必須小心。
物件字面量語法{prop:'value'}
與程式碼塊{}
相似。 因此,當將物件字面量放置在嵌入式箭頭函式中時,需要將其包裝在一對括號中:()=>({prop:'value'})
。
最後,函式的過度巢狀模糊了程式碼意圖。減少箭頭函式巢狀的一個好方法是將它們提取到變數中。或者,嘗試使用更好的特性,如async/await
語法。
對於箭頭函式,你還有什麼建議,歡迎留言討論。
程式碼部署後可能存在的BUG沒法實時知道,事後為了解決這些BUG,花了大量的時間進行log 除錯,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug。
原文:dmitripavlutin.com/javascript-…
交流
文章每週持續更新,可以微信搜尋「 大遷世界 」第一時間閱讀和催更(比部落格早一到兩篇喲),本文 GitHub github.com/qq449245884… 已經收錄,整理了很多我的文件,歡迎Star和完善,大家面試可以參照考點複習,另外關注公眾號,後臺回覆福利,即可看到福利,你懂的。