柯里化函数本身不自动提供默认值,需手动实现:通过闭包缓存参数与默认值,支持占位符跳过中间参数,允许默认值为函数以延迟求值,并在执行时合并参数(传入值优先)。

JavaScript 中柯里化函数本身不自动提供缺失参数的默认值,需要手动实现默认逻辑。核心思路是:在每次调用时检查参数是否充足,若不足则返回新函数;同时允许提前指定部分默认值,并在最终执行时合并传入参数与默认值。
用闭包保存默认参数和已传参数
柯里化函数常借助闭包缓存已传入的参数和预设的默认值。你可以把默认值作为配置项传入柯里化工厂函数,或在调用链中动态注入。
- 定义一个 curryWithDefaults 工厂函数,接收原函数和默认参数对象(如 { timeout: 5000, retry: 3 })
- 每次调用时,将新参数与默认值合并(新参数优先级高于默认值)
- 只在参数个数达到原函数 length 时才真正执行,否则返回继续接收参数的函数
支持占位符(如 _)跳过中间参数
实际使用中,有时只想指定第 1 和第 3 个参数,第 2 个留默认。这时可用占位符机制来标记“此处暂不传值”,后续用默认值填充。
- 约定一个特殊值(比如全局 _ 或 Symbol.for('curry.placeholder'))作为占位符
- 在参数合并阶段,对每个位置:如果传入的是占位符,就取对应默认值;否则用传入值
- 例如:fn(1, _, 3) → 合并后为 [1, defaults[1], 3]
延迟绑定默认值(运行时决定)
有些默认值依赖环境(如当前时间、用户配置、API 响应),不适合在 curry 时静态写死。可让默认值以函数形式提供,在真正执行时调用。
- 默认配置支持函数类型:{ timeout: () => Math.random() * 1000 + 1000 }
- 合并参数时,对每个默认值判断 typeof === 'function',是则执行获取真实值
- 这样既保持柯里化链的纯度,又支持动态默认逻辑
结合 bind 与 rest 参数简化实现
现代 JS 可用箭头函数 + rest 参数 + bind 快速构造带默认值的柯里化变体,适合简单场景。
- const curried = (a = 10, b = 'hello') => (c) => console.log(a, b, c)
- 或用 bind 预置部分默认:fn.bind(null, undefined, 'defaultB'),再配合参数检查补全
- 注意:bind 不会自动跳过 undefined,需在内部判断并替换为默认值
关键不在语法糖,而在明确“谁负责提供默认值”——是 curry 工厂、调用方、还是执行时的上下文。选对时机和方式,柯里化就能自然承载默认逻辑,而不是变成参数拼凑的负担。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











