vue.js响应式系统用weakmap作为依赖收集第一层索引,核心作用是以响应式对象为键、安全映射其depsmap并避免内存泄漏;它支持get/set时按需查找,不遍历、不阻塞gc,专用于reactive对象和数组,ref等基本类型则由refimpl自行维护dep。

Vue.js 响应式系统用 WeakMap 作为依赖收集的“第一层索引”,核心作用是把响应式对象和它的属性级依赖表关联起来,同时避免内存泄漏。
WeakMap 是对象到依赖表的映射入口
Vue 内部维护一个全局的 targetMap = new WeakMap()。每当调用 reactive(obj),这个原始对象 obj 就作为键存入 targetMap;它的值不是数据本身,而是一个 Map(常称 depsMap),专门记录该对象每个属性对应的副作用函数集合。
- 键必须是对象 —— 天然匹配“哪个响应式对象”这一层级
- 弱引用语义 —— 如果
obj在其他地方不再被持有,GC 可回收它,targetMap 中对应条目也自动消失 - 不支持遍历或查键存在性 —— Vue 不需要枚举所有响应式对象,只在 get/set 时按需查找
依赖收集发生在属性读取时(get 拦截器)
当执行 effect(() => console.log(state.count)),访问 state.count 触发 Proxy 的 get 拦截器:
- 检查是否存在正在运行的
activeEffect - 通过
targetMap.get(state)拿到它的 depsMap - 再用
depsMap.get('count')获取该属性对应的 effect 集合(Set) - 把当前
activeEffect加入这个 Set
整个过程依赖 WeakMap 快速定位对象级依赖表,且不干扰对象生命周期。
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
WeakMap 不负责所有响应式类型
它主要服务 reactive() 创建的对象和数组:
- 数组的索引访问(如
arr[0])和 length 变化,靠重写原型方法 + 把依赖挂载在代理后的数组实例上,仍走同一套 WeakMap → Map → Set 链路 - 基本类型(
ref(1))不进 WeakMap,而是由RefImpl实例自身维护一个dep: Set - Map / Set 等集合类型,内部也用 WeakMap 缓存其代理实例与依赖关系,逻辑一致
配合 effect 自身的 deps 清理旧依赖
每个 effect 函数自带一个 deps: Set,里面存的是它上次收集到的所有属性依赖(即那些 Set 引用)。重新执行前会先调用 cleanup():
- 遍历自己的
deps,从每个 dep Set 中删掉自己 - 再触发新的 track,建立当前上下文下的最新依赖
- 这样既保证通知精准,又防止“脏依赖”残留
WeakMap 虽不直接参与 cleanup,但它让整条依赖链的起点可被安全释放 —— 对象一丢,后续 Map 和 Set 自然失去宿主,不会滞留。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










