老生常谈,函数柯里化(curring)

  柯里化这个概念确实晦涩难懂,没有深入思考过的人其实真的很难明白这是一个什么东西。看起来简单、简单到或许只需要一行代码:

const curry = fn => (…args) => fn.bind(null, …args);

  是的,就是这么简单。

  如果单纯的去理解这一句代码,实在太痛苦了,不妨拆开来,一点一点的去看,也不妨再笨点,先尝试着写成传统的ES5,我们用arguments 去代替 ...args 慢慢理解。貌似是下面这样

const curry = function(fn){
   return function (){ // 1
      return fn.bind(null, arguments)  //2
   } 
}

 

  可是看着感觉有点不对劲呢?

  显然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
   } 
}

  这下好像和我们之前看的差不多了嘛,但是这他妈拆了半天函数啥也没说,不是等于放屁吗?

  好吧,如果直接去看概念搞不懂的话,换个思路,看代码,如果看懂了,再去想概念不就更加容易理解了吗?

  接着再看

  fn.bind(null, _args)

  这句话是干啥子的,

  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函数都只是把之前的参数和这次的参数收集到一个数组里,然后返回一个新的函数,而且这个函数已经默认带了之前传入的所有参数。是的,柯里化就是一个参数收集器,返回新的函数而已。

  这玩意有啥用?

  很多文章都已经说明了,大家可以去参考一下别的文章就可以了。

  希望能对大家理解柯里化有些帮助。

  参考链接:

  http://www.webhek.com/post/javascript-bind.html

       https://www.zhangxinxu.com/wordpress/2013/02/js-currying/ 

      

posted @ 2019-04-08 21:20  断劫断念  阅读(1031)  评论(0编辑  收藏  举报