需求
实现sum函数,使其可以传入不定长参数,以及不定次数调用
//示例
console.log(sum(1,2)(3)()) //6
console.log(sum(2,3,4,5)(1,2)(3)(4)()) //23
需求分析
实现sum函数我们可以考虑可以使用闭包的形式来实现
-
因为每次传参,所以我们不知道这是不是最后一次,如果是最后一个括号,则就要执行
-
我们可以通过每次调用时对传入参数的个数来判断目前是否是最后一个括号
-
如果有参数就说明是调用,那么我们就将参数保存到外面的容器中
-
如果没有参数则说明是调用
-
如果最后是调用时,我们只需要将所有的参数累加即可
function add (...args) {
return args.reduce((pre, cur) => pre + cur)
}
function currying (fn) {
// 作为参数存储的容器
let argArr = []
// 中间容器,用来判断传入是否有传入参数
return function temp (...arg) {
// 只要传入的参数不为0,就继续将参数交给容器
if (arg.length) {
// 使用扩展运算符,将result中的值进行更新
argArr = [...argArr, ...arg]
return temp
}
// 如果没有参数的话则说明是最后一个括号,也就是执行
else {
let val = fn(...argArr)
argArr = []
return val
}
}
}
let sum = currying(add)
console.log(sum(1, 2, 3, 4)(1)()) //15
console.log(sum(1,2)(3)()) //6
reduce回顾
reduce数组方法,接收两个参数,第一个为一个累加器函数,第二个参数为初始值
比如对数组累加,我们如果不设置初始值,也就是不设置第二个参数,那么累加器中
第一个参数pre就是数组的第一个元素,cur就是第二个元素,也就是第一次就会访问到
数组的第一个和第二个元素
如果传递了初始值,那么数组索引就会从0开始,也就是第一个cur是数组第一个元素,
pre为传递的初始值
通俗一点来说:
如果不写初始值,那么元素累加就从索引为1开始,初始值默认为数组第一个元素
写上初始值就从索引为0开始。
累加函数有四个参数(preValue,curValue,index,arr)
每一项都要有一个返回值
闭包回顾
闭包的一般形式就是函数返回函数,在内层函数中可以访问外层函数中的变量
这样可以延长变量的作用域,使得变量可以长期保存。比如我们在这个案例中使用闭包
来保存每次传递的参数。闭包可能会造成内存泄露,其它造成内存泄漏的场景还有:
- 没有被清理的定时器
- 意外的全局变量
- 没有清理对DOM的引用