轉自 http://simplyy.space/article/577c5b0dcbe0a3e656c87c24
多個連續的箭頭函數與柯里化
高階函數
高階函數定義:將函數作為參數或者返回值是函數的函數。
所以高階函數分兩種:
- 是我們常見的
sort
,reduce
等函數。 - 返回值是函數的函數。
一般而言,我們要理解常見的高階函數還是很容易的。比如:
function add(a) { return function(b) { return a + b } } var add3 = add(3) add3(4) === 3 + 4 //true
add 函數 在 es6 里的寫法等價為
let add = a => b => a + b
其實以上就是 柯里化函數 只不過用 es6 寫,變了一個樣子,后面詳細介紹它的原理和特點。
多個連續的箭頭函數
but 當一堆箭頭函數在你面前的時候,你會不會有一絲猶豫,我在此之前就是一臉懵逼。。。比如我看到下面的 redux-thunk 的源碼(沒錯整個源碼只有14行)里的多個連續箭頭函數的時候。。。
// 形如 a => b => c => {xxx}
那怎么輕松理解這些箭頭干了啥呢,當我看了柯里化后,瞬間就懂了,
多個連續箭頭函數就是 es6的多次柯里化的寫法
柯里化
我們先看 stackoverflow 的關於如何理解多個箭頭函數的最高票回答,
他說 這就是柯里化函數。(This is a curried function)
wiki 的柯里化定義: 把接受多個參數的函數變換成接受一個單一參數的函數,並且返回(接受余下的參數而且返回結果的)新函數的技術
好,現在懂沒,我來簡單說一下。
關鍵就是理解柯里化,其實可以把它理解成,柯里化后,將第一個參數變量存在函數里面了(閉包),然后本來需要n個參數的函數可以變成只需要剩下的(n - 1個)參數就可以調用,比如
let add = x => y => x + y let add2 = add(2)
本來完成 add 這個操作,應該是
let add = (x, y) => x + y
它需要倆參數,而現在 add2 函數完成同樣操作只需要一個參數,這在函數式編程中廣泛應用。
詳細解釋一下,就是 add2 函數 等價於 有了 x 這個閉包變量的 y => x + y
函數
並且此時 x = 2,所以此時調用
add2(3) === 2 + 3
回歸正題
let add = x => y => x + y
add 函數按照 wiki 的定義可以理解成只柯里化了一次,那么下面這種呢?
a => b => c => {xxx}
n 個連續箭頭組成的函數實際上就是柯里化了 n - 1次。
具體調用過程如下:
前 n - 1 次調用,其實是提前將參數傳遞進去,並沒有調用最內層函數體,最后一次調用才會調用最內層函數體,並返回最內層函數體的返回值。
結合上文可知,這里的多個連續箭頭(無論倆個箭頭函數三個及以上)函數連在一起 就是在柯里化。
所以連續箭頭函數就是多次柯里化函數的 es6 寫法。
let test = a => b => c => {xxx}
調用特點
let test = a => b => c => {xxx}
比如對於上面的 test
函數,它有 3 個箭頭, 這個函數要被調用 3 次 test(a)(b)(c)
,前兩次調用只是在傳遞參數,只有最后依次調用才會返回 {xxx}
代碼段的返回值,並且在 {xxx}
代碼段中可以調用 a,b,c
柯里化函數的功能
- 可以惰性求值
- 可以提前傳遞部分參數