标准答案
- 柯里化可以把 fn(a, b, c) 转成 curried(a)(b)(c) 或 curried(a, b)(c) 这类调用形式。
- 实现核心是闭包保存已经收集的参数。
- 当收集参数数量达到原函数 arity 时,用这些参数调用原函数。
- 参数未收集够时,返回一个新函数继续收集后续参数。
- 实际实现还要考虑 this 绑定、默认参数、剩余参数和占位符等扩展能力。
题目解析
柯里化的本质是延迟执行和参数复用。比如固定某些通用参数后,得到一个更具体的新函数,后续调用只需要传剩下的参数。
手写题里常用 fn.length 判断需要几个参数,但它有边界:默认参数、rest 参数不会按直觉计入 length。所以回答时要说明这是常见简化版本。
柯里化和偏函数应用很接近,但不完全一样。柯里化强调把多参数函数转换成连续单参或分批传参形式,偏函数强调预先固定一部分参数。
代码示例
简化版 curry 根据 fn.length 判断参数是否收集完成。
JavaScript
function curry(fn, ...presetArgs) {
return function curried(...nextArgs) {
const args = [...presetArgs, ...nextArgs]
if (args.length >= fn.length) {
return fn.apply(this, args)
}
return curry(fn, ...args)
}
}常见误区
- 只支持 curried(a)(b)(c),不支持 curried(a, b)(c) 这类分批传参。
- 没有说明 fn.length 在默认参数和 rest 参数场景下的限制。
- 实现时丢失 this,导致依赖调用上下文的函数行为变化。