理解 JavaScript 中的高階函式

Jothy發表於2018-11-13

理解 JavaScript 中的高階函式


原文作者:Sukhjinder Arora
譯者:UC 國際研發 Jothy

寫在最前:歡迎你來到“UC國際技術”公眾號,我們將為大家提供與客戶端、服務端、演算法、測試、資料、前端等相關的高質量技術文章,不限於原創與翻譯。

本文將讓大家瞭解什麼是高階函式以及如何在 JavaScript 中使用它們。
如果你正在學習 JavaScript,那麼你應該見過高階函式這個術語。 它雖然聽起來很複雜,但其實並不難。
使 JavaScript 適合函數語言程式設計的原因是它接受高階函式。
高階函式在 JavaScript 中廣泛使用。 如果你已經用 JavaScript 程式設計了一段時間,你可能已經在不知不覺中用過它們了。
要完全理解這個概念,首先必須瞭解函數語言程式設計以及一等函式(First-Class Functions)的概念。

理解 JavaScript 中的高階函式 什麼是函數語言程式設計
在大多數簡單的術語中,函式式是一種程式設計形式,你可以將函式作為引數傳遞給其他函式,並將它們作為值返回。 在函數語言程式設計中,我們以函式的形式思考和程式設計。
JavaScript,Haskell,Clojure,Scala 和 Erlang 是部分實現了函數語言程式設計的語言。

理解 JavaScript 中的高階函式一等函式
如果你在學習 JavaScript,你可能聽說過 JavaScript 將函式視為一等公民。 那是因為在 JavaScript 及其他函數語言程式設計語言中,函式是物件。
在 JavaScript 中,函式是一種特殊型別的物件。 它們是 Function objects。例如:
理解 JavaScript 中的高階函式
為了證明 JavaScript 中函式是物件,我們可以這樣做:
理解 JavaScript 中的高階函式
注意 - 雖然這在 JavaScript 中完全有效,但這被認為是 harmful 的做法。 你不應該向函式物件新增隨機屬性,如果不得不這樣做,請使用物件。
在 JavaScript 中,你對其他型別(如物件,字串或數字)執行的所有操作都可以對函式執行。 你可以將它們作為引數傳遞給其他函式(回撥函式),將它們分配給變數並傳遞它們等等。這就是 JavaScript 中的函式被稱為一等函式的原因。

理解 JavaScript 中的高階函式將函式賦值給變數
我們可以在 JavaScript 中將函式賦值給變數。 例如:
理解 JavaScript 中的高階函式
我們也可以傳遞它們。 例如:
理解 JavaScript 中的高階函式

理解 JavaScript 中的高階函式將函式作為引數傳遞
我們可以將函式作為引數傳遞給其他函式。 例如:
理解 JavaScript 中的高階函式
既然我們已經知道一等函式是什麼了,那就讓我們開始學習 JavaScript 中的高階函式叭~

理解 JavaScript 中的高階函式高階函式
高階函式是對其他函式進行操作的函式,操作可以是將它們作為引數,或者是返回它們。 簡單來說,高階函式是一個接收函式作為引數或將函式作為輸出返回的函式。
例如,Array.prototype.map,Array.prototype.filter 和 Array.prototype.reduce 是語言中內建的一些高階函式。

理解 JavaScript 中的高階函式動手實踐高階函式
讓我們看看一些內建高階函式的例子,看看它與不使用高階函式的方案對比如何。


Array.prototype.map

map() 方法通過呼叫對輸入陣列中每個元素呼叫回撥函式來建立一個新陣列。
map() 方法將獲取回撥函式中的每個返回值,並使用這些值建立一個新陣列。
傳遞給 map() 方法的回撥函式接受 3 個引數:element,index 和 array。
我們來看一些例子:


例 1:

假設我們有一個數字陣列,我們想要建立一個新陣列,其中包含第一個陣列中每個值的兩倍。 讓我們看看如何使用和不使用高階函式來解決問題。

不使用高階函式
理解 JavaScript 中的高階函式

使用高階函式 map
理解 JavaScript 中的高階函式
使用箭頭函式語法將更簡短:
理解 JavaScript 中的高階函式
例 2:
假設我們有一個包含不同人的出生年份的陣列,我們想要建立一個包含其年齡的陣列。 例如:
不使用高階函式
理解 JavaScript 中的高階函式

使用高階函式
理解 JavaScript 中的高階函式
Array.prototype.filter
filter() 方法會建立一個新陣列,其中包含所有通過回撥函式測試的元素。 傳遞給 filter() 方法的回撥函式接受3個引數:element,index 和 array。
讓我們看看一些例子:

例 1:

假設我們有一個包含名稱和年齡屬性的物件陣列。 我們想要建立一個只包含成年人(年齡大於或等於18)的陣列。
不使用高階函式
理解 JavaScript 中的高階函式

使用高階函式
理解 JavaScript 中的高階函式
Array.prototype.reduce
reduce 方法對呼叫陣列的每個元素執行回撥函式,最後生成一個單一的值並返回。 reduce 方法接受兩個引數:1)reducer 函式(回撥),2)一個可選的 initialValue。
reducer 函式(回撥)接受四個引數:accumulator,currentValue,currentIndex,sourceArray。
如果提供了 initialValue,則累加器將等於 initialValue,currentValue 將等於陣列中的第一個元素。
如果沒有提供 initialValue,則累加器將等於陣列中的第一個元素,currentValue 將等於陣列中的第二個元素。

例 1:

假設我們要對一個數字陣列的求和:
使用高階函式 reduce
理解 JavaScript 中的高階函式
每次對陣列中的某個值呼叫 reducer 函式,累加器都會保留上一次 reducer 函式操作返回的結果,並將 currentValue 設定為陣列的當前值。 最後把結果儲存在 sum 變數中。
我們還可以為它提供初始值:
理解 JavaScript 中的高階函式

不使用高階函式
理解 JavaScript 中的高階函式
可以看到使用高階函式使我們的程式碼更清晰簡潔。複製程式碼


理解 JavaScript 中的高階函式建立我們自己的高階函式
到目前為止,我們看到了語言中內建的各種高階函式。 現在讓我們建立自己的高階函式。
我們假設 JavaScript 沒有原生的 map 方法。 我們可以自己構建它,從而建立我們自己的高階函式。 假設我們有一個字串陣列,我們希望把它轉換為整數陣列,其中每個元素代表原始陣列中字串的長度。
理解 JavaScript 中的高階函式
在上面的例子中,我們建立了一個高階函式 mapForEach ,它接受一個陣列和一個回撥函式 fn。 它迴圈遍歷傳入的陣列,並在每次迭代時在 newArray.push 方法呼叫回撥函式 fn 。
回撥函式 fn 接收陣列的當前元素並返回該元素的長度,該元素儲存在 newArray 中。 for 迴圈完成後,newArray 被返回並賦值給 lenArray。

理解 JavaScript 中的高階函式結論
我們已經瞭解了高階函式和一些內建的高階函式,還學習瞭如何建立自己的高階函式。

簡而言之,高階函式是一個可以接收函式作為引數,甚至返回一個函式的函式。 它就像常規函式一樣,只是多了接收和返回其他函式的附加能力,即引數和輸出。

以上。如果你發現這篇文章有用,請為我點贊~?


英文原文: https://blog.bitsrc.io/understanding-higher-order-functions-in-javascript-75461803bad


好文推薦:HTTP/3 來啦,你還在等什麼?趕緊了解一下 (https://mp.weixin.qq.com/s/ZH5GjB_LjMmfgO6_tYHJdA )

————————————————————————————————

“UC國際技術”致力於與你共享高質量的技術文章
歡迎微信搜尋 UC國際技術 關注我們的公眾號
或者將文章分享給你的好友


相關文章