柯里化和偏函数(偏应用,后续称偏函数)的区别在于处理参数上的区别,二者都是函数式编程的一种工具。主要就是方便组合函数的使用,此外理解柯里化
与偏函数
原理是需要闭包函数
的前置知识的。
柯里化 currying
柯里化即将一个多元函数
转为一元函数
的过程。
💡 多元函数
仅接受一个参数的被称作一元函数
, 二个参数称作二元函数
,以此类推…
1 2 3 4 5
| const double = (n) => n * 2
const add = (x, y) => x + y
|
了解完 多元函数
后再来实现 柯里化
🔩 柯里化实现
在js中fn.bind()
方法就可以当做一个柯里化方法来使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const curry = (bindFn, ...firstArg) => { return (...curArg) => { const args = [...firstArg, ...curArg]
if (args.length < bindFn.length) { return curry(bindFn, ...args) }
return bindFn(...args) } }
|
🌰 使用示例
1 2 3 4 5 6 7 8 9
| const add = (x, y) => x + y
const curryAdd = curry(add)
console.log(curryAdd(1))
console.log(curryAdd(1)(2))
|
🍐 其他使用场景
实现一个针对不同情况的系统日志打印。可以这么实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const logHelper = (type, message) => { if (type === 'DEBUG') { console.debug(message) } else if (type === 'ERROR') { console.error(message) } else { console.log(type, message) } }
const logDebug = curry(logHelper)('DEBUG') const logError = curry(logHelper)('ERROR') const logInfo = curry(logHelper)('INFO')
|
以上可知 柯里化
所预处理的参数都是,从左至右处理。 如果遇到像 setTimeout
这种,柯里化就无法很好的完成工作。这时候就需要另一个 偏函数
偏函数 partail application
假如要实现一个每隔16ms执行一次的操作,使用 setTimeout(fn, 16)
。 这时候柯里化固定的就是第一个参数fn
,解决这种情况使用的是偏函数
🌰 使用示例
1 2 3 4 5 6 7 8
| const nextAnimeFrame = partial(setTimeout, undefined, 16)
console.log('第一次', Date.now()) nextAnimeFrame(() => { console.log('第二次', Date.now()) })
|
🔩 偏函数实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| const partial = (fn, ...partialArg) => { return (...fullArg) => { const args = [...partialArg] let arg = 0
for (let i = 0; i < fn.length && arg < fullArg.length; i++) { if (args[i] === undefined) { args[i] = fullArg[arg++] } }
return fn(...args) } }
|