响应式中的那些奇怪的小问题(未完待续)

5 阅读1分钟

ref 中的 value 是如何初始化的

function ref(value){
    const refObj = {
        get value(){
            truck(obj,'value')
            return value
        },
        set value(newVal){
            value = newVal
            trigger(obj,'value')
        }
    }
    return refObj
}

利用了闭包的特性,由于导出的 refObj 对象中包含了对 value 的引用,所以 value 不参与垃圾回收,并成为了 obj 的一个参数

targetMap 和 depsMap 为什么一个用的是 Map() 而另外一个用的是 WeakMap()?

根本原因在于, WeakMap 仅支持对象和 Symbol 作为键而不支持原始值作为键

这是因为 WeakMap 和 Map 的根本区别在于 WeakMap 中的键值对是可被垃圾回收的,而这种删除的依据基于内存是否有对“键”的引用,而由于原始值不存在引用,这也就是 WeakMap 不支持原始值作为键的原因

在响应式的设计中,考虑到内存泄露的问题,优先使用 WeakMap 作为依赖收集的数据结构,但是由于 WeakMap 无法使用原始值作为键的原因,所以 depsMap 只能采用 Map 来存储数据

到底是如何进行依赖追踪的?

在 Vue 中,activeEffect 是一个全局变量,其作用是追踪当前正在执行的副作用函数。

而当响应式变量被访问时,它会捕获当前的 activeEffect,从而明确是哪个函数触发了该响应式变量的“陷阱”。

随后,这个 activeEffect 便会被收集到响应式变量的依赖列表中,以便在变量更新时被重新执行。