账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    实现函数柯里化,最后返回柯里化函数的时候为什么不需要额外传参?
    70
    0

    在学习函数柯里化的时候看到这篇文章 https://github.com/yygmind/bl...,
    作者的一个实现思路是这样的:

    function currying(fn, length) {
      length = length || fn.length;     // 注释 1
      return function (...args) {            // 注释 2
        return args.length >= length    // 注释 3
            ? fn.apply(this, args)            // 注释 4
          : currying(fn.bind(this, ...args), length - args.length) // 注释 5
      }
    }
    
    // Test
    const fn = currying(function(a, b, c) {
        console.log([a, b, c]);
    });
    
    fn("a", "b", "c") // ["a", "b", "c"]
    fn("a", "b")("c") // ["a", "b", "c"]
    fn("a")("b")("c") // ["a", "b", "c"]
    fn("a")("b", "c") // ["a", "b", "c"]

    底下有一个评论说,"可以不用在递归 currying 的时候传入 length - args.length,因为 bind 返回的函数的 length 已经是 length - args.length 了",他给出的代码是:

    function currying(fn) {
          return function (...args) {
            return args.length >= fn.length
              ? fn.apply(this, args)
              : currying(fn.bind(this, ...args))
          }
        }

    为什么bind后返回的函数的形参个数,即length刚好是length - args.length呢?
    这个length - args.length 我的理解是计算还需要多少个参数才可以实际运算fn,第一次递归后,currying的第二个参数就是这个差值,不再是函数形参个数,之后拿这个差值与柯里化后的函数实际接受的参数数目比较,如果这个数目达到了差值,就不需要再递归了。而按照这个评论的说法, bind 返回的函数的length就是length - args.length,因此不需要给递归的currying传length - args.length,这是怎么看出来的?bind的第二个参数会在bind返回的函数实际执行的时候传递给它,基于这一点我们才可以收集参数,最后统一运算,但是为什么bind返回的函数的length就刚好是length - args.length呢?

    1
    打赏
    收藏
    点击回答
    您的回答被采纳后将获得:提问者悬赏的 10 元积分
        全部回答
    • 共 0 条
    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部