函数柯里化是将多参数函数转换为一系列单参数函数的技术,用于参数复用、延迟执行和构造可复用的响应式函数工厂,但不直接参与依赖收集,需与Proxy/Dep协同工作。

函数柯里化本身不直接提供依赖收集能力,但它可以和响应式机制协同工作,用于构造可配置、可复用的响应式函数工厂。真正的依赖收集必须由 Proxy(或 defineProperty)配合闭包化的依赖容器(如 Dep)完成;柯里化的作用是把“谁要响应什么”这个逻辑参数化、延迟化。
柯里化在响应式系统中的定位
它不是依赖收集的执行者,而是依赖注册的“包装器”和“预设器”。比如你希望某个计算函数只监听 obj.name,但不想每次手动写 watch(obj, 'name', fn),就可以用柯里化封装成:
- watchName = watch('name') —— 返回一个等待目标对象的函数
- watchName(obj)(fn) —— 等价于 watch(obj, 'name', fn),此时 fn 才被真正注册为 name 属性的依赖
这样就把“监听哪个属性”提前固化,后续只需传入对象和响应函数,提升复用性和可读性。
如何用柯里化辅助依赖注册流程
假设你已有基础响应式结构(Proxy + Dep),柯里化可嵌入到依赖注册环节:
- 定义 createWatcher = (key) => (target) => (effect) => { const dep = getDep(target, key); dep.add(effect); }
- 调用时:createWatcher('count')(reactiveObj)(() => console.log('count changed'))
- 其中 getDep(target, key) 是标准的依赖映射查找(查 targetMap → depsMap → dep)
- 柯里化让 effect 的注册与 target、key 解耦,支持函数组合、条件注入或批量绑定
结合 track/trigger 的实际协作方式
柯里化不参与 track(读取时收集)或 trigger(修改时触发),但它能控制何时、对谁、以何种粒度调用 track:
- 在 effect 函数内部访问属性时,track 自动发生;而柯里化可帮你生成“更窄作用域”的 effect
- 例如:makeGetter = (key) => (obj) => obj[key],再柯里化为 getName = makeGetter('name'),后续 getName(observedObj) 就会触发对 name 的 track
- 这种写法让依赖路径显式、可测试,也便于做静态分析或 devtools 插桩
注意边界:柯里化不能替代响应式核心
它无法解决以下问题,必须由 Proxy/Dep 配合完成:
- 属性读取时自动调用 track
- 属性赋值时自动调用 trigger
- 嵌套对象的递归代理(reactive)
- 依赖清理、副作用调度、更新队列等运行时逻辑
柯里化只是让这些能力更容易组织、复用和组合,而不是实现它们。










