1.定义
把原来接收多个参数的函数改造成接收单个参数,并返回一个接收余下参数且返回结果的新函数,这样的"改造",叫做函数柯里化
//原函数:接收两个参数
function sum(a,b){console.log(a+b)}
sum(1,2)//3
//柯里化:
function sum(a){
return function(b){
console.log(a+b);
}
}
sum(1)(2); // 3
2.本质和特点
可以看到把一个函数进行柯里化,其本质是闭包,
利用闭包来保存已传入的参数,当参数数量达到要求时执行原函数
柯里化的函数有如下特点:
- 参数复用:固定部分参数,生成更小元的函数
- 延迟执行:分批次传入参数,最后一步执行计算
- 函数组合:便于创建可复用的函数片段
- 单一职责:每个函数只处理一个参数
3.两个以上参数的函数柯里化如何处理?
要求:把function sum(a,b,c){}柯里化,然后可以这样调用sum(1)(2)(3)
function sum(a){
return function(b){
return function(c){
console.log(a+b+c)
}
}
}
要求:五个形参的sum函数柯里化,然后可以这样调用sum(1)(2,3,4)(5),即形参个数不固定
步骤:
- 1.保存不定长参数
- 2.判断参数的个数
-
- 2.1.长度到5:累加
-
- 2.2.长度没到5:返回函数,接收剩余参数
//思路:保存不定长的参数,若未达到长度要求,则返回函数去接收剩余参数,若达到要求则累加5个参数
const nums = []
function sum(...args) {
nums.push(...args)
//2.判断参数的个数
if (nums.length >= 5) {
//2.1.长度到5:累加
const res = nums.slice(0, 5).reduce((p, v) => p + v, 0)
nums.length = 0 // 清空数组
return res
} else {
//2.2.长度没到5:返回函数,接收剩余参数
return sum
}
}
// 测试代码
console.log("第一次调用:")
console.log(sum(1, 2)(3)(4, 5)) // 应该返回15
console.log("第二次调用:")
console.log(sum(1)(2)(3)(4)(5)) // 应该返回15
console.log("第三次调用:")
console.log(sum(1, 2, 3, 4, 5)) // 应该返回15
4.函数参数的个数为自定义,如何实现柯里化?
要求:
function sumMaker(){
//
}
//调用:
const sum4=sumMaker(4)
sum4(1,2)(3)(4)
const sum6=sumMaker(6)
sum6(1,2)(3)(4,5,6)
思路:复用上节逻辑,形参为传入形参的个数
代码:
function sumMaker(length) {
//1.保存不定长参数
let nums = []
function sum(...args) {
// 2.判断参数的个数
nums.push(...args)
// 2.1.长度到5:累加
if (nums.length >= length) {
const res = nums.slice(0, length).reduce((p, v) => p + v, 0)
nums = [] // 重置数组
return res
} else {
// 2.2.长度没到5:返回函数,接收剩余参数
return sum // 返回函数继续接收参数
}
}
return sum
}
// 测试代码
const sum5 = sumMaker(5)
console.log("测试1: sum5(1, 2)(3)(4, 5)")
console.log(sum5(1, 2)(3)(4, 5)) // 应该返回15
console.log("测试2: sum5(1)(2)(3)(4)(5)")
console.log(sum5(1)(2)(3)(4)(5)) // 应该返回15
console.log("测试3: sum5(1, 2, 3, 4, 5)")
console.log(sum5(1, 2, 3, 4, 5)) // 应该返回15
// 测试不同的长度
const sum3 = sumMaker(3)
console.log("测试sum3(1)(2)(3):")
console.log(sum3(1)(2)(3)) // 应该返回6
5.函数柯里化的使用场景
使用场景:为函数预制通用函数,以供多次重复调用
示例:
//初始写法:
function typeOfText(type){
function isundefined(obj){
//return typeof obj==='undefined'
return typeof obj===type
}
return isundefined
}
//优化写法:
function typeOfText(type){
return function (obj){
return typeof obj===type
}
}
//改成箭头函数:
const typeOfTest=type=>obj=> typeof obj===type
//验证:
console.log(typeOfTest("string"))

被折叠的 条评论
为什么被折叠?



