JS中精巧的自动柯里化实现方法(3)

现在再来看:

function curry(fn) {
 function _c(restNum, argsList) {
  return restNum === 0 ?
   fn.apply(null, argsList) :
   function(x) {
    return _c(restNum - 1, argsList.concat(x));
   };
 }
 return _c(fn.length, []); // 递归开始
}

是不是开始清晰起来了?

ES6写法的由于使用了 数组解构 及 箭头函数 等语法糖,看上去精简很多,不过思想都是一样的啦~

// ES6
const curry = fn => {
 const _c = (restNum, argsList) => restNum === 0 ?
  fn(...argsList) : x => _c(restNum - 1, [...argsList, x]);

 return _c(fn.length, []);
}

与其他方法的对比

还有一种大家常用的方法:

function curry(fn) {
 const len = fn.length;
 return function judge(...args1) {
  return args1.length >= len ?
  fn(...args1):
  function(...args2) {
   return judge(...[...args1, ...args2]);
  }
 }
}
// 使用箭头函数
const curry = fn => {
 const len = fn.length;
 const judge = (...args1) => args1.length >= len ?
  fn(...args1) : (...args2) => judge(...[...args1, ...args2]);
 return judge;
}

与本篇文章先前提到的方法对比的话,发现这种方法有两个问题:

依赖ES6的解构(函数参数中的 ...args1 与 ...args2);

性能稍差一点。

性能问题

做个测试:

console.time("curry");
const plus = curry((a, b, c, d, e) => a + b + c + d + e);
plus(1)(2)(3)(4)(5);
console.timeEnd("curry");

在我的电脑(Manjaro Linux,Intel Xeon E5 2665,32GB DDR3 四通道1333Mhz,Node.js 9.2.0)上:

本篇提到的方法耗时约 0.325ms

其他方法的耗时约 0.345ms

差的这一点猜测是闭包的原因。由于闭包的访问比较耗性能,而这种方式形成了两个闭包:fn 和 len,前面提到的方法只形成了 fn 一个闭包,所以造成了这一微小的差距。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/866.html