如何实现下面的科里化函数
/ 假设有一个 curry 函数可以做到柯里化
var addCurry = curry(add);
addCurry(1)(2) // 3
题目分析
通过curry处理后返回的函数addCurry,连续调用addCurry(1)(2)(3),只有在最后一次括号调用的时候才输出的结果。
- 通过这个现象,我们分析下面几个问题
- 怎么样能实现addCurry(1)(2)(3)这样连续的括号调用呢?
- 思考:每次括号调用完成后,我们是不是可以返回curry(add),直到最后一次才运行累加运算。
- 这时候问题来了,因为是连续调用,那怎么样才能知道当前这次调用的addCurry(val),是否是最后一次调用呢?
- 通过获取传入addCurry的函数fn的fn.length,获取到fn的形参长度。这样就可以直到第几次调用可以累加结果了。
- 继续第二个问题,那之前输入的数据怎么样才能在最后一次拿到,然后进行累加运算呢?
- 我们是不是可以通过闭包的形式保存每次调用传入的参数,留给最后一次累加。
代码实现以下
const curry = function(fn, args) {
const length = fn.length; // 获取fn形参的长度
let _args = args || []; // 用来保存每次addCurry调用传入的实参,既然要保存肯定要形成闭包
return function() {
for (let i = 0; i < arguments.length; i ++) {
_args.push(arguments[i])
}
// 当前执行获取到所有参数的长度,小于length,说明还要继续传参,这时我们返回 addCurry(fn, _args),便于下一次的括号调用
if (_args.length < length) {
return curry(fn, _args)
} else {
return fn(..._args)
}
}
}
const add = function(a, b, c) {
return a + b + c;
}
const addCurry = curry(add);
addCurry(1)(2)(3);
- 记一次函数科里化简单实现的笔记