JavaScript的函数柯里化
1. 什么是函数柯里化
函数柯里化又称部分求和,一个柯里化的函数首先会接收一些参数,接收了这些参数后,该函数不会马上进行执行,而是继续返回另一个函数,等到函数被真正需要求值时,之前传入的所有参数都会被一次性用于执行函数。可以说函数柯里化是一种函数的转换,它是指将一个函数从可调用的fn(a,b,c)转换为可调用的fn(a)(b)©或者fn(a,b)©或者fn(a)(b,c)。
说白了,函数的柯里化就是固定部分参数,返回一个接受剩余参数的函数。它的核心思想就是把多参数传入的函数拆成一个个单参数或者少参数(或部分参数)的函数,内部再返回调用下一个单参数(或部分参数)函数,依次处理剩余的参数。
注意:柯里化不会调用函数,只是对函数进行转换。
2. 函数柯里化的优缺点
2.1 优点
- 柯里化之后,没有丢失任何参数
- 可以轻松生成偏函数
- 入口单一
- 易于测试和复用
2.2 缺点
- 函数嵌套多
- 占内存,有可能导致内存泄漏(本质是配合闭包实现的)
- 效率差(使用递归)
- 变量存取慢,访问性很差
3. 柯里化的适用场景
- 参数复用:即若函数要重复使用到的参数,可以利用柯里化将复用的参数存储起来,不需要每次都传相同的参数。
- 延时执行:传入参数个数没有满足原函数入参的个数,都不会立即返回结果,而是返回一个函数。
4. 案例
如今年报名软考的考生。由于报考的都是软考,费用都是128,所以这两就是固定部分参数,而考生的名字和年龄都会改变的,所以柯里化先将subject和spand存起来,等传入name和age之后才执行函数。
柯里化之一
function test(subject,spand){
return function candidate(name,age){
return `我是${name},今年${age}岁了,我报考了${subject},一共花了${spand}。`
}
}
// 直接调用柯里化后的函数
let c1 = test('软考',128)('aaa',10)
let c2 = test('软考',128)('bbb',100)
// 先用t1接返回的函数candidate,
// 再设置一个变量c3接t1()传入name和age之后返回的结果
let t1 = test('考生3',128)
let c3 = t1('ddd',23)
let t2 = test('考生4',128)
let c4 = t2('ccc',23)
console.log('考生1:'+c1+' 考生2:'+c2)
console.log('考生3:'+c3+' 考生4:'+c4)
运行结果:
注:两种方式都实现了函数柯里化,打印了返回的结果。
柯里化之二
function test(subject,spand){
return function candidate(name){
return function candidate1(age){
return `我是${name},今年${age}岁了,我报考了${subject},一共花了${spand}。`
}
}
}
// 直接调用柯里化后的函数
let c1 = test('软考',128)('aaa')(100)
let c2 = test('软考',128)('bbb')(1000)
// 先用t3接返回的函数candidate,
// 再设置一个变量tt1接t3()传入name之后的函数
// 最后设置c3接tt1()传入age之后的函数的结果
let t3 = test('考生3',128)
let tt1= t3('eee')
let c3 = tt1(23)
let t4 = test('考生4',128)
let tt2 = t3('fff')
let c4 = tt2(23)
console.log('考生1:'+c1+' 考生2:'+c2)
console.log('考生3:'+c3+' 考生4:'+c4)
运行结果:
注:也可以换为fn(a,b)©(d)这种方式,主要看函数到底柯里化到多少个函数了。
好囖,以上☝️就是函数的柯里化的内容啦~🤗