「翻譯」淺談JavaScript中的高階函數

如果你正在學習JavaScript,那麼你一定碰到過高階函數這個術語,儘管它聽起來很複雜,但其實不是的。高階函數的採用使得JavaScript適合用來做函數式編程。

在JavaScript中,高階函數的使用隨處可見。如果你已經用JavaScript寫過一陣子的代碼,那麼你可能已經在不知情的情況下使用過它了。

為了完全理解這個概念,你首先要了解什麼是函數式編程以及頭等函數的概念。

什麼是函數式編程

在大多數簡單的術語中,函數式編程是一種編程形式,讓你能將函數作為參數傳遞給其他函數並且能夠將函數作為值返回。在函數式編程中,我們依據函數來思考和寫代碼。

JavaScript,Haskell,Clojure,Scala和Erlang等語言是能夠用來做函數式編程的語言。

頭等函數

如果你正在學習JavaScript,你應該有耳聞JavaScript將函數作為一等公民。那是因為在JavaScript或其他函數式編程語言中函數是作為對象存在的。

在JavaScript中,函數是一類特殊的對象,它們是Function對象。舉個例子:

「翻譯」淺談JavaScript中的高階函數

為了證明在JavaScript中函數是對象,我們能這樣做:

「翻譯」淺談JavaScript中的高階函數

注意!雖然這在JavaScript是有效的,但這是一種不良的實踐。你不應該給函數對象添加屬性值,最好還是使用對象來添加。

在JavaScript中,你能對對象、字符串、數字類型做的操作,你同樣能在函數上操作。就如你能將它們作為參數給函數,把它們賦值給變量然後傳遞它們等。這就是為什麼在JavaScript中函數被視為頭等函數。

將函數賦值給變量

我們能夠將函數賦值給一個變量,就如:

「翻譯」淺談JavaScript中的高階函數

當然我們還能傳遞它,就如:

「翻譯」淺談JavaScript中的高階函數

將函數作為參數

我們能將函數作為參數傳遞給另一個函數,就如:

「翻譯」淺談JavaScript中的高階函數

現在我們知道什麼是頭等函數了,讓我們來繼續深入高階函數。

高階函數

高階函數是對其他函數進行操作的函數,可以將它們作為參數或返回它們。 簡單來說,高階函數是一個函數,它接收函數作為參數或將函數作為輸出返回。

例如,Array.prototype.map,Array.prototype.filter和Array.prototype.reduce是語言中內置的一些高階函數。

高階函數實戰

讓我們來看一些語言中內置的高階函數,然後跟不使用高階函數的解決方案對比一下。

1. Array.prototype.map

map()方法通過將輸入數組中的每個元素作為參數來調用提供的回調函數來創建一個新數組。 map()方法將從回調函數中獲取每個返回的值,並使用這些值創建一個新數組。

傳遞給map()方法的回調函數接受3個參數:element,index和array。

讓我們來看些例子:

  • 例1#

假設我們有一個數組,我們想要創建一個新數組,其中的值是原數組的值的兩倍。讓我們看看使用和不使用高階函數的解決方案。

不使用高階函數

「翻譯」淺談JavaScript中的高階函數

使用高階函數

「翻譯」淺談JavaScript中的高階函數

我們能用箭頭函數來讓代碼更簡短一點:

「翻譯」淺談JavaScript中的高階函數

  • 例2#

假設我們有一個包含不同人的出生年的數組,我們想要創建一個他們年齡的數組。

不使用高階函數

「翻譯」淺談JavaScript中的高階函數

使用高階函數

「翻譯」淺談JavaScript中的高階函數

2. Array.prototype.filter

filter()方法創建一個新數組,包含著所有通過了回調函數校驗的元素。 傳遞給filter()方法的回調函數接受3個參數:element,index和array。

讓我們來下例子:

  • 例1#

假設我們有一個包含姓名和年齡的對象數組,我們要創建一個只有年齡大於等於18的人的對象數組。

不使用高階函數

「翻譯」淺談JavaScript中的高階函數

使用高階函數

「翻譯」淺談JavaScript中的高階函數

3. Array.prototype.reduce

reduce方法對數組的每個成員執行回調函數,然後產生單個輸出值。 reduce方法接受兩個參數:回調函數和可選的initialValue(初始值)。

reducer的回調函數接受四個參數:accumulator,currentValue,currentIndex,sourceArray。

如果提供了初始值,則accumulator將等於initialValue,currentValue將等於數組中的第一個元素。

如果沒有提供initialValue,則accumulator將等於數組中的第一個元素,currentValue將等於數組中的第二個元素。

  • 例1#

假設我們需要計算數組中值的總和:

使用高階函數

「翻譯」淺談JavaScript中的高階函數

每次在數組中的值上調用reducer函數時,accumulator都會保留從reducer函數返回的先前操作的結果,並將currentValue設置為數組的當前值。 最後,結果存儲在sum變量中。

我們能給這函數提供一個初始值:

「翻譯」淺談JavaScript中的高階函數

不使用高階函數

「翻譯」淺談JavaScript中的高階函數

你能看到使用了高階函數的話能使我們的代碼更加乾淨整潔不囉嗦。

創造我們自己的高階函數

到目前為止,我們看到了語言中內置的各種高階函數。 現在讓我們來創造自己的高階函數。

我們假設JavaScript沒有原生map方法。 我們可以自己創造它,從而創建我們自己的高階函數。

假設我們有一個字符串數組,然後我們希望將此數組轉換為整數數組,其中每個元素表示原數組中字符串的長度。

「翻譯」淺談JavaScript中的高階函數

在上面的例子中,我們創建了一個高階函數mapForEach,它接受一個數組和一個回調函數。此函數循環遍歷提供的數組,並在每次迭代時在newArray.push函數內部調用回調函數。

回調函數fn接收數組的當前元素並返回該元素的長度,該元素存儲在newArray中。for循環完成後,返回newArray並將其分配給lenArray。

結語

我們已經瞭解了高階函數和一些內置的高階函數。 我們還學習瞭如何創建自己的高階函數。

簡而言之,高階函數是一個函數,它可以接受函數作為參數,甚至可以返回一個函數。 高階函數就像常規函數一樣,只是具有接收和返回其他函數的附加能力。

轉載自我的百家號(http://baijiahao.baidu.com/builder/preview/s?id=1616366107595017691)


分享到:


相關文章: