day7 Reactive响应式原理
WeakMap
WeakMap 是 JavaScript 中的一种内置集合类型,它提供了一种以弱引用方式存储键值对的机制。WeakMap 的特点是键只能是对象,并且对键的引用是弱引用,这意味着如果键对象没有其他引用,它们将被自动垃圾回收
- 键必须是对象:
WeakMap的键只能是对象,不能是原始值(如字符串、数字等)。 - 弱引用:与
Map不同,WeakMap对键的引用是弱引用。这意味着如果键对象没有其他引用,它们将被自动垃圾回收,即使它们作为WeakMap的键仍然存在。 - 不可迭代:
WeakMap没有提供直接的迭代方法(如keys()、values()和entries()),因此无法遍历其中的键值对。 - 无法获取大小:
WeakMap没有类似size属性的方法来获取其大小。由于键的引用是弱引用,键对象的数量并不直接对外部可见。 - 应用场景:
WeakMap在某些场景下非常有用,例如在存储私有数据时,可以使用键对象作为存储私有数据的唯一标识符。
在 vue3源码的 reactive.ts中的 createReactiveObject 函数有这样一段场景
function createReactiveObject(
target: Target,
isReadonly: boolean,
baseHandlers: ProxyHandler<any>,
collectionHandlers: ProxyHandler<any>,
proxyMap: WeakMap<Target, any>
) {
// ----- 省略 --------
// target already has corresponding Proxy
// 目标已存在相应的代理
const existingProxy = proxyMap.get(target)
if (existingProxy) {
return existingProxy
}
// ----- 省略 --------
const proxy = new Proxy(
target,
targetType === TargetType.COLLECTION ? collectionHandlers : baseHandlers
)
// 将原对象target 作为键,代理对象proxy作为值
proxyMap.set(target, proxy)
return proxy
}
从这段代码可以得到使用target作为键用来判断当前target之前是否存在代理对象,当同一个对象无论使用reactive创建多少个代理对象,他们的代理对象都是同一个