函数柯理化

278 阅读1分钟

函数式编程有一个概念,叫做柯里化(currying),意思是将多参数的函数转换成单参数的形式。这里也可以使用柯里化。

\

function currying(fn, n) {

  return function (m) {

    return fn.call(this, m, n);

  };

}

\

function tailFactorial(n, total) {

  if (n === 1) return total;

  return tailFactorial(n - 1, n * total);

}

\

const factorial = currying(tailFactorial, 1);

\

factorial(5) // 120

上面代码通过柯里化,将尾递归函数tailFactorial变为只接受一个参数的factorial。

\

第二种方法就简单多了,就是采用 ES6 的函数默认值。

\

function factorial(n, total = 1) {

  if (n === 1) return total;

  return factorial(n - 1, n * total);

}

\

factorial(5) // 120

上面代码中,参数total有默认值1,所以调用时不用提供这个值。

\

总结一下,递归本质上是一种循环操作。纯粹的函数式编程语言没有循环操作命令,所有的循环都用递归实现,这就是为什么尾递归对这些语言极其重要。对于其他支持“尾调用优化”的语言(比如 Lua,ES6),只需要知道循环可以用递归代替,而一旦使用递归,就最好使用尾递归。