前端柯粒化函数( 加法 + 去重 + 取最大值 )

303 阅读2分钟

本文已参与「 新人创作礼 」活动,一起开启掘金创作之路

关于如何进行图片优化 - 适合的才是最好的

柯粒化函数在前端各种场景应用的已经是非常的多。闭包的场景用法也是非常之多。当如如何写出更优雅的代码,其实还是需要一些技巧,以及对JS的基础知识的掌握程度了。后续有机会我会对如何设计一个基础库做一些讲解。

前端有很多诸如的操作add(1)(2)(3) 等等都有很多用法之多。前端也提供了很多聚合函数用来配合处理相关。

function add (...args) {
  return args.reduce((a, b) => a + b)
}
function currying (fn) {
  let args = []
  return function _c (...newArgs) {
    if (newArgs.length) {
      args = [...args,...newArgs]
      return _c
    } else {
      return fn.apply(this, args)
    }
  }
}
let addCurry = currying(add)

一个是内聚函数,一个是颗粒化函数。

这样就组合成了链式加法,add(1 , 2 )(3) (4)() 里面的

关键代码是currying 闭包函数 _c 把函数做了扁平化数组处理。

还有就是Array 提供的reduce 这个方法的牛逼用法太多了。后面我讲用这个方法介绍几个特别的用法。

上面这个方法实现起来还是看起来比较的散列。还有一个方式是:

function add(...args) {

  // 将参数绑定到add上
  // 此时f其实还是add函数,但已经固定了一些参数,所以并不是原来的add函数
  // 用bind返回新函数以保证满足**柯里化保留参数**的特性
  var f = add.bind(null/*this不用绑定*/, ...args) 

  // 重新实现这个bound add函数的toString方法
  // f参与运算应该被当成args的和,与f自己再接收的参数无关
  // 考虑到lazy的特性,还是需要时再计算,但又没了缓存,每次用都会重新计算
  // 如果有需要,可以改成有缓存的版本
  f.toString = () => {
    return args.reduce((a, b) => a + b, 0)
  }

  return f
}

这个方法是不是代码更加经典,主要是通过bind这个方式,对args参数数组处理。最后通过toString的方法,进行累加。

这个时候你会发现reduce的牛逼之处了吧。

example : add(1)(2,3)(4)(5)(6)()

//取出数组中的最大值
var max = arr.reduce(function (prev, cur) {
  return Math.max(prev,cur);
});
//数组去重
var newArr = arr.reduce((pre , cur)=>{ 
  !pre.includes(cur) && pre.push(cur);
  return pre; 
} , [])

这些牛逼的用法,还是很有用处的。

注意这里面还是有点繁琐。例如:每次叠加之后,都有一个执行空参数函数() , 那有没有办法去掉呢?