day7 Reactive响应式原理

42 阅读2分钟

day7 Reactive响应式原理

WeakMap

WeakMap 是 JavaScript 中的一种内置集合类型,它提供了一种以弱引用方式存储键值对的机制。WeakMap 的特点是键只能是对象,并且对键的引用是弱引用,这意味着如果键对象没有其他引用,它们将被自动垃圾回收

  1. 键必须是对象:WeakMap 的键只能是对象,不能是原始值(如字符串、数字等)。
  2. 弱引用:与 Map 不同,WeakMap 对键的引用是弱引用。这意味着如果键对象没有其他引用,它们将被自动垃圾回收,即使它们作为 WeakMap 的键仍然存在。
  3. 不可迭代:WeakMap 没有提供直接的迭代方法(如 keys()values() 和 entries()),因此无法遍历其中的键值对。
  4. 无法获取大小:WeakMap 没有类似 size 属性的方法来获取其大小。由于键的引用是弱引用,键对象的数量并不直接对外部可见。
  5. 应用场景: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创建多少个代理对象,他们的代理对象都是同一个