編寫高質量箭頭函數的5個最佳作法

做者:Dmitri Pavlutin
譯者:前端小智
來源:dmitripavlutin.com
點贊再看,養成習慣

本文 GitHub https://github.com/qq44924588... 上已經收錄,更多往期高贊文章的分類,也整理了不少個人文檔,和教程資料。歡迎Star和完善,你們面試能夠參照考點複習,但願咱們一塊兒有點東西。javascript

箭頭功能值得流行。 它的語法簡潔明瞭,使用詞法綁定綁定 this,它很是適合做爲回調。在本文中,經過了解決學習5個最佳實踐,以便咱們能夠從中學習更多箭頭函數的知識,並從它身上得到更多的好處。前端

1. 箭頭函數名推斷

JS 中的箭頭函數是匿名(anonymous)的:函數的name屬性是''java

( number => number + 1 ).name; // => ''

在調試會話或調用堆棧分析期間,匿名函數被標記爲anonymous。 不幸的是,anonymous程序不提供有關正在執行的代碼的任何線索。 git

這裏是執行匿名函數的代碼的調試會話:github

clipboard.png

右邊的調用堆棧由兩個標記爲anonymous的函數組成,咱們沒法從這樣的調用堆棧信息中得到任何有用的信息。面試

幸運的是,函數名推斷(ES2015的功能)能夠在某些條件下檢測到函數名稱。 名稱推斷的思想是JS 能夠從其語法位置肯定箭頭函數名稱: 從保存函數對象的變量名稱中獲取。json

咱們來看看函數名稱推斷的工做原理:數組

const increaseNumber = number => number + 1;

increaseNumber.name; // => 'increaseNumber'

由於變量increaseNumber保存了箭頭函數,因此 JS 決定使用increaseNumber做爲該函數的名稱。所以,箭頭函數的名稱爲 'increaseNumber'服務器

第1個實踐:微信

一個好的作法是使用函數名稱推斷來命名箭頭函數。

如今咱們用使用名稱推斷的代碼檢查一個調試會話:

clipboard.png

由於箭頭函數有名稱,因此調用堆棧提供了有關正在執行的代碼的更多信息。

  • 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);

重構將箭頭函數提取到變量readItemsJsonhandleButtonClick中。 嵌套級別從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

原文:https://dmitripavlutin.com/ja...


交流

文章每週持續更新,能夠微信搜索「 大遷世界 」第一時間閱讀和催更(比博客早一到兩篇喲),本文 GitHub https://github.com/qq449245884/xiaozhi 已經收錄,整理了不少個人文檔,歡迎Star和完善,你們面試能夠參照考點複習,另外關注公衆號,後臺回覆福利,便可看到福利,你懂的。

相關文章
相關標籤/搜索