这是我参与「掘金日新计划 · 8 月更文挑战」的第22天,点击查看活动详情
什么是柯里化?
维基百科:柯里化(curring)是,将一个接收多参数的函数转换为一个接收单一参数的函数,并能返回一个接收余下参数的新函数。这么一种技术。
先看一个例子。
// 普通的add函数
function add(x, y) {
return x + y
}
// Currying后
function curryingAdd(x) {
return function (y) {
return x + y
}
}
add(1, 2) // 3
curryingAdd(1)(2) // 3
柯里化有哪些作用?
- 参数复用
- 提前确认
- 延迟执行
例子参见:www.jianshu.com/p/2975c25e4…
函数柯里化
如何封装一个通用函数实现函数柯里化?
核心:
1.要思考如何缓存每一次传入的参数
2.传入的参数和目标函数的入参做比较
// 通过闭包的方式缓存参数
var curry = (fn) => {
let params = [];
const next= (...args) => {
params = [...params,...args];
console.log(params)
// fn.length是目标函数的形参个数
if(params.length<fn.length){
return next;
}else{
return fn.apply(fn,params)
}
}
return next
}
// 使用
var sum = (a,b,c) => {
return a+b+c;
}
var fn = curry(sum)
console.log(fn(1)(2)(3)) // 6
面试题
// 实现一个add方法,使计算结果能够满足如下预期:
add(1)(2)(3) = 6;
add(1, 2, 3)(4) = 10;
add(1)(2)(3)(4)(5) = 15;
function add() {
// 用一个数组存储函数的全部参数
var _args = Array.prototype.slice.call(arguments);
// 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值
var _adder = function() {
_args.push(...arguments);
return _adder;
};
// 利用toString隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回
_adder.toString = function () {
return _args.reduce(function (a, b) {
return a + b;
});
}
return _adder;
}
add(1)(2)(3) // 6
add(1, 2, 3)(4) // 10
add(1)(2)(3)(4)(5) // 15
add(2, 6)(1) // 9
分析:
var _args = Array.prototype.slice.call(arguments)
这行的作用是,用一个数组存储函数的全部参数。
如: add(1) _args===[1]
再如: add(1,2,3) _args===[1,2,3]
_adder函数,保存了每一次函数调用时的入参。
如:add(1, 2, 3)(4)
1:add(1,2,3)
_args = [1,2,3]
add(1,2,3)返回一个函数_adder(4)
2._adder(4)
_args = [1,2,3,4]