本文已参与「 新人创作礼 」活动,一起开启掘金创作之路
柯粒化函数在前端各种场景应用的已经是非常的多。闭包的场景用法也是非常之多。当如如何写出更优雅的代码,其实还是需要一些技巧,以及对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;
} , [])
这些牛逼的用法,还是很有用处的。
注意这里面还是有点繁琐。例如:每次叠加之后,都有一个执行空参数函数() , 那有没有办法去掉呢?