实现函数柯里化,最后返回柯里化函数的时候为什么不需要额外传参?

发布于 2022-09-11 21:38:42 字数 1438 浏览 9 评论 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呢?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

囚我心虐我身 2022-09-18 21:38:42

function.prototype.bind

bind 方法设置了返回的函数对象的 length 为 (输入的)fn.length - args.length

束缚m 2022-09-18 21:38:42

bind的时候args展开的是实参,数量当然就是传入的实参数量。

这种写法只适用于es6,es5以前还是需要第一种写法。(虽然第一种写法也用到了参数展开,但是可以很容易改写成非展开的写法,而第二种则依赖于展开操作的副作用)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文