如果想要实现一个类似add的操作,正常情况下普通写法如下
function add(a, b) {
return a + b
}
但是如果我们此时想要再加一个参数的话,那么必须改写代码为
function add(a, b, c) {
return a + b + c
}
这样去改写代码显然不能满足我们的需求,如果此时出现动态参数的n的形式当然函数内部可以写成从参数1
+ ... + 参数n
,但是如果我们再提出一个想要链式调用的需求的话,这种思想是不可能达到需求的。如果能从函数内部入手的话,让add函数本身返回的还是一个可执行函数的话,在借助动态参数代码如下
function add(...args1) {
const fn = (...args2) => {
return args1.concat(args1).reduce((pre, curr) => pre + curr)
}
return fn
}
这样似乎可是实现链式调用了,但是貌似只能使用一次链式调用,类似add(1)(2) => 3,但是如果我想直接调用或者多个链式调用是无法满足的,类似add(1)无效、add(1)(2)(3)无效。如果考虑到多个链式操作的话可以引入递归的思想
function add(...args1) {
const fn = (...args2) => {
return add(...args1, ...args2)
}
return fn
}
那么处理加法的逻辑在哪做呢?可以把这个逻辑挂载在fn上,这样的话每次可以利用add的参数去收集待要处理的数据,暴漏出fn上挂载的函数去做具体的逻辑,代码如下
function add(...args1) {
const fn = (...args2) => {
return add(...args1, ...args2)
}
fn.value = () => {
return args1.concat(args1).reduce((pre, curr) => pre + curr)
}
return fn
}
这样的话可以这样使用add(1).value()、add(1, 2)(3).value()、add(1)(2)(3).value()。既然已经做到这一步了,我们完全可以让用户自定义处理逻辑,扩展如下
function curryAction(...args1) {
const fn = (...args2) => {
return curryAction(...args1, ...args2)
}
fn.value = (callback) => {
if (typeof callback === 'function') {
return callback(...args1)
}
return args1.concat(args1).reduce((pre, curr) => pre + curr)
}
return fn
}
curryAction
函数不局限于只能做加法运算了,可以做其他我们想做的操作,例如做乘法curryAction(1, 2)(3)(4).value((...args) => args.reduce((pre, curr) => pre * curr))