[譯]在 JavaScript 中 爲何你應當使用 map 和 filter 來替代 forEach

當你須要將一個數組或一部分數組複製到一個新數組時,首選 mapfilter,而不是 forEach前端

諮詢工做對我來講最大的好處之一是我能夠看到無數的項目。這些項目有大有小,使用的編程語言和開發人員能力差別很大。儘管我認爲有不少模式都應該放棄使用,但 JavaScript 語言中的這種模式尤爲要棄用:使用 forEach 建立新數組。該模式實際上很是簡單,看起來像這樣:react

const kids = [];
people.forEach(person => {
  if (person.age < 15) {
    kids.push({ id: person.id, name: person.name });
  }
});
複製代碼

這段代碼的意思是,處理一個包含全部人的數組,以找出每一個年齡小於 15 歲的人。而後選擇 person 對象中的其中幾個字段做爲 'kids' 對象,並將其複製到 kids 數組中。android

雖然這是有效的,但這是很是必要的(參見編程範例)編碼方式。你可能有所懷疑,這有什麼不對?要理解這一點,讓咱們首先熟悉兩個朋友 mapfilterios

mapfilter

在 2015 年,mapfilter 做爲 ES6 特性集的一部分被引入 JavaScript。它們是數組的方法,容許在 JavaScript 中進行更多函數式編程。像在函數式編程世界中同樣,這兩種方法都沒有改變原始數組。相反,它們都返回一個新數組。它們都接受函數類型的單個參數。而後在原始數組中的每一項上調用此函數以生成結果數組。讓咱們看看這些方法的做用:git

  • map:每項調用函數處理後的值存放到返回的新數組中。
  • filter:每項調用函數處理後的值決定該項是否應該放在方法返回的新數組中。

在同一個團體中他們也有第三個朋友,但較少使用。這位朋友的名字是 reducegithub

如下是能夠查看實際操做結果的簡單示例:編程

const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(number => number * 2); // [2, 4, 6, 8, 10]
const even = numbers.filter(number => number % 2 === 0); // [2, 4]
複製代碼

既然咱們知道 mapfilter 會作什麼,讓咱們接下來看一個我但願前面的示例應當如何編寫的例子:後端

const kids = people
  .filter(person => person.age < 15)
  .map(person => ({ id: person.id, name: person.name }));
複製代碼

若是您想知道 map 中使用的 lambda 的語法,請參閱此 Stack Overflow answer 以獲取解釋。數組

那麼這個實現究竟有什麼好處:promise

  • 關注點分離:過濾和更改數據格式是兩個獨立的問題,使用單獨的方法能夠分離關注點。
  • 可測試性:爲實現這兩個目的,一個簡單的、純函數的方法能夠輕鬆地針對各類行爲進行單元測試。值得注意的是,初始實現並不像它依賴於其範圍 (kids 數組)以外的某些狀態那樣純粹。
  • 可讀性:因爲這些方法具備過濾數據或更改數據格式的明確目的,所以很容易看出正在進行何種操做。特別是由於有那些同類功能的函數,如 reduce
  • 異步編程:forEachasync/await 不能很好地協同工做。另外一方面,map 提供了一個可以結合 promises 和 async/await 的有效模式。在下一篇博文中有關於此問題的更多信息。

另外一個值得注意的地方是,當你想引發反作用時(例如更改全局狀態),不該當使用 map。特別是在不使用或存儲 map 方法的返回值的狀況下。

結論

mapfilter 的使用提供了許多好處,例如關注點分離、可測試性、可讀性和對異步編程的支持。所以,對我來講這是一個明智的選擇。然而,我常常遇到使用 forEach 的開發人員。雖然函數式編程可能使人懼怕,這些方法有也具備來自該世界的某些特徵,對它們並不用懼怕。在響應式編程中,mapfilter 也被大量使用,感謝 RxJS 的貢獻,響應式編程如今愈來愈多地在 JavaScript 世界中使用。所以,下次你要寫一個 forEach 時,首先要考慮其餘方法。但要注意,它們可能會永久改變您的編碼方式。

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索