何为柯里化传参
简单地说就是参数可以分次传入,等效于一次传入
比如:
console.log(sum(1)(2)()) //3
console.log(sum(1,2)) //3
明白了柯里化传参
我们来看看它的实现,
这里拿最简单的加法举例子
直接上完整代码:
let sum = function() {
//以下三种方式都是把arguments对象转换成数组
//在这里储存传进来的参数
//let args = Array.prototype.slice.call(arguments)
//let args = [].slice.call(arguments);
let args = [...arguments];
return (function f() {
if (arguments.length !== 0) {
//如果闭包函数存在参数,则把参数添加到参数组args
args.push(...arguments);
//递归调用
return f
} else {
//如果参数为空,说明参数累加完毕,对最终args进行计算
return args.reduce((a, b) => a + b);
}
})
}
至此,对柯里化传参的实现就结束了
这里的sum返回了一个闭包函数,
这个闭包函数在自身参数非空的时候会递归调用自身,并且对args添加本次递归前传入闭包的参数,
当递归到闭包参数为空时,把最终集大成的args拿去做真正的计算。
这里对args实现了三种方法的类数组转数组方法
先讲讲最简单的
let args = [...arguments];
- 这里用了ES6的扩展运算符直接展开类数组然后声明成数组
let args = [].slice.call(arguments);
- 这个涉及到
slice()
和call()
方法。 - 可以注意的是,
slice()
如果参数为空,它将返回一个与原数组相同的数组,也就是copy了一遍。 - 而这里
call()
传入了arguments作为this指向。 - 最终结果就是copy了一个跟arguments相同的数组出来
- 这个涉及到
let args = Array.prototype.slice.call(arguments)
- 其实是跟上面的一样的,只不过是从原型上调用的
slice()
方法,减少了对原型链的查找,性能更高了
- 其实是跟上面的一样的,只不过是从原型上调用的