什么是函数柯里化
百度百科:在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。
从上面这段话中,我们可以获取以下信息点
- 柯里化(currying)函数接收一个函数作为参数
- 柯里化函数返回一个新函数
- 返回的新函数接收余下参数且返回结果
根据上面的信息,我们可以先写出柯里化函数的简单骨架
// 接受一个函数作为参数(fn)
function currying(fn) {
// 返回一个新函数
return function() {
// TODO
}
}
这样我们已经完成了上述的第一第二点,接下来我们要如何让新函数接收余下参数且返回结果呢
我们先看一个例子
var add = currying(function () {
let sum = 0
for (let i = 0; i < arguments.length; i++) {
sum += arguments[i]
}
return sum
})
console.log(add(1)(2, 3)(4)()) // 10
上面是函数柯里化比较常见的示例,add()方法会不断返回函数,直到不再收到任何参数(最后的括号里边不传值),再根据所有传入的参数进行结果的计算与返回
也就是说:
- 柯里化函数返回的新函数,可能还会继续返回函数
- 当最后返回的函数不再收到任何参数,则根据所有传入的参数计算并返回结果
根据上面的例子,我们继续完善我们的柯里化函数
function currying(fn) {
// 先创建一个空数组,来接受所有参数,这里用到了闭包
const allArgs = []
// 返回的新函数next
const next = function() {
// 判断是否收到参数
if(arguments.length === 0) {
// 如果不再收到参数 则计算并返回最后的结果
return fn.apply(null, allArgs)
} else {
// 如果还继续传入参数,
// 则将传入的参数放入我们创建的参数数组中
const args = Array.prototype.slice.call(arguments)
allArgs.push(...args)
// 因为还接受到参数,所以继续返回next函数
return next
}
}
return next
}
如此一来,一个简单的柯里化函数就完成了
如果我们不想在没有接收到参数的时候才计算并返回结果,我们可以利用toString()的隐式调用实现这个需求,先看个例子
const ret = add(1)(2, 3)(4)(5)
console.log(ret, typeof ret)
/*
ƒ () {
if (arguments.length === 0) {
return fn.apply(null, allArgs)
} else {
const args = Array.prototype.slice.call(arguments)
allArgs.push(...args)
return next
… "function"
*/
可以看到ret输出的是函数内部的代码,而typeof ret确实"function"
这是由于console.log()方法会调用ret的toString()方法,如果ret没有该方法的话,就会继续往原型链上找,这里调用的是Function中的toString()方法
除了console.log()会调用ret的toString(),对ret进行计算等操作也会调用toString(),利用该特性,我们可以重写next()的toString()方法,来返回我们的结果
function currying(fn) {
// 先创建一个空数组,来接受所有参数,这里用到了闭包
const allArgs = []
// 返回的新函数next
const next = function() {
// 判断是否收到参数
if(arguments.length === 0) {
// 如果不再收到参数 则计算并返回最后的结果
return fn.apply(null, allArgs)
} else {
// 如果还继续传入参数,
// 则将传入的参数放入我们创建的参数数组中
const args = Array.prototype.slice.call(arguments)
allArgs.push(...args)
// 因为还接受到参数,所以继续返回next函数
return next
}
}
next.toString = function() {
console.log('toString')
return fn.apply(null, allArgs)
}
return next
}
console.log(add(1)(2, 3)(4)())
const ret = add(1)(2, 3)(4)(5)
console.log(ret + 1)
/*
10
toString
26
*/
函数柯里化是将一个多参数的函数转换为一系列单参数函数的技术。柯里化函数接收一个原始函数,返回一个新的函数,这个新函数可以接收剩余参数,并在所有参数都提供后计算结果。通过闭包和数组存储参数,柯里化函数可以在接收到所有参数前继续返回函数。此外,利用`toString()`方法,可以在调用时立即计算结果。柯里化在JavaScript中常用于预填充参数、提高代码复用性和创建部分应用函数。
777

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



