柯里化這個概念確實晦澀難懂,沒有深刻思考過的人其實真的很難明白這是一個什麼東西。看起來簡單、簡單到或許只須要一行代碼:javascript
const curry = fn => (…args) => fn.bind(null, …args);
是的,就是這麼簡單。html
若是單純的去理解這一句代碼,實在太痛苦了,不妨拆開來,一點一點的去看,也不妨再笨點,先嚐試着寫成傳統的ES5,咱們用arguments 去代替 ...args 慢慢理解。貌似是下面這樣java
const curry = function(fn){ return function (){ // 1 return fn.bind(null, arguments) //2 } }
但是看着感受有點不對勁呢?web
顯然2處的arguments已經和上面的args已經不是一個東西了,這裏的arguments是1處函數調用時的參數,因此要改進下數組
const curry = function(fn){ let args = [].slice.call(arguments, 1) // 這句話的意思是差很少等於 let args = arguments.slice(1) ,可是argumets不是數組(僞數組),因此不能這麼寫 return function (){ // 1
let _args = args.concat([].slice.call(arguments)) // 拼接出新的arguments
return fn.bind(null,_args) //2
} }
這下好像和咱們以前看的差很少了嘛,可是這他媽拆了半天函數啥也沒說,不是等於放屁嗎?
wordpress
好吧,若是直接去看概念搞不懂的話,換個思路,看代碼,若是看懂了,再去想概念不就更加容易理解了嗎?函數
接着再看 post
fn.bind(null, _args)this
這句話是幹啥子的,spa
bind() 方法會建立一個新函數,當這個新函數被調用時,它的 this 值是傳遞給 bind() 的第一個參數, 它的參數是 bind() 的其餘參數和其本來的參數。
懂了嗎?
function a(){ return [].slice.call( arguments) } a(1,2,3) // [1,2,3] var _a = a.bind(null, 4,5) _a(1,2,3) // [4,5,1,2,3]
其實只是拼接了參數而已,並且bind返回的是一個函數,等着被調用,
這樣看來每次調用curry函數都只是把以前的參數和此次的參數收集到一個數組裏,而後返回一個新的函數,並且這個函數已經默認帶了以前傳入的全部參數。是的,柯里化就是一個參數收集器,返回新的函數而已。
這玩意有啥用?
不少文章都已經說明了,你們能夠去參考一下別的文章就能夠了。
但願能對你們理解柯里化有些幫助。
參考連接: