Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
本题难度:⭐ ⭐
答:
柯里化函数是将一个多参数函数转换成多个单参数函数,也就是将一个 n 元函数转换成 n 个一元函数的编程技巧。
偏函数是指将一系列参数固定到一个函数上,生成另一个较小算术数的函数的编程技巧。
柯里化函数和偏函数的区别是:
柯里化函数
f(x, y, z) 只能转化为 f(x)(y)(z),有多少个参数,就转化成多少个函数调用
偏函数
f(x, y, z) 可以转化成 f(x, y)(z),也可以转化成 f(x)(y, z)
他们俩的目的都是为了避免频繁调用具有相同参数函数的同时,又能够轻松的重用。
重点:他们俩的实现都用到了闭包。
柯里化函数
假设我们有一个求立方体体积的函数。
function getVolume(width, length, height) {
return width * length * height
}
如果我们碰到的立方体的长和宽老是不变,只有高度经常变化。
const volume1 = getVolume(1, 2, 3)
const volume2 = getVolume(1, 2, 4)
const volume3 = getVolume(1, 2, 5)
console.log(volume1) // 6
console.log(volume1) // 8
console.log(volume1) // 10
我们就这么写:
function getVolume (width) {
return length => {
return height => {
return width * length * height
}
}
}
之后碰到长和宽不变的立方体就可以这样计算体积。
const getTwoWithVolume = getVolume(1)(2)
const volume1 = getTwoWithVolume(3)
const volume2 = getTwoWithVolume(4)
const volume3 = getTwoWithVolume(5)
console.log(volume1) // 6
console.log(volume1) // 8
console.log(volume1) // 10
不怎么变化的长和宽就被记录到了闭包里,第一个参数 width 被记录在 getVolume 函数的闭包里,第二个参数 length 被记录在匿名函数的闭包里。
上面的 getVolume 函数用箭头函数来写长这样,箭头函数的代码确实很简洁,但可能不好理解。
const getVolume = width => length => height => width * length * height
偏函数
偏函数的实现也用到了闭包,代码如下:
const partial = function (fn, ...args) {
return function (...rest) {
return fn(...args, ...rest)
}
}
const getVolume = (width, length, height) => width * length * height
const twoMultiplyHeight = partial(getVolume, 1, 2) // 宽固定为1,长固定为2,高在不断变化
console.log(twoMultiplyHeight(3)) // 6
console.log(twoMultiplyHeight(4)) // 8
console.log(twoMultiplyHeight(5)) // 10
const tenMultiplyHeight = partial(getVolume, 5, 2) // 宽固定为5,长固定为2,高在不断变化
console.log(tenMultiplyHeight(2)) // 20
console.log(tenMultiplyHeight(3)) // 30
console.log(tenMultiplyHeight(4)) // 40
const tenMultiplyLengthAndHeight = partial(getVolume, 10) // 宽固定为10,长和高不断变化
console.log(tenMultiplyLengthAndHeight(2, 5)) // 100
console.log(tenMultiplyLengthAndHeight(3, 4)) // 120
console.log(tenMultiplyLengthAndHeight(3, 3)) // 90
以宽固定为1,长固定为2,高在不断变化为例,闭包中记录的就是固定的前两个参数。
拓展
我们平时经常写的 ajax 请求,可能在不知不觉中就用到了偏函数。
比如所有的请求都要在 headers 里写一样的 token,又比如根据请求方法单独抽离出用得多的 get 请求和 post 请求,你可能会写出类似下面的代码:
function request (method, url, headers) {
// ...
}
const headers = {
authorization: 'xxx'
}
const getRequest = url => request('get', url, headers)
const postRequest = url => request('post', url, headers)
getRequest('/api/getBookList')
postRequest('/api/login')
结尾
如果我的文章对你有帮助,你的👍就是对我的最大支持^_^
你也可以关注《前端每日一问》这个专栏,防止失联哦~
我是阿林,输出洞见技术,再会!
上一篇:
下一篇: