小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
前文我们学习到 Map 类, Map 对象表示一组称为键的值, 每个键关联着一个值, 形成映射关系. 今天来学习另一个(弱映射)类 WeakMap
JavaScript WeakMap
在 JavaScript 中的对象, 我们经常见到的, 对象的键名 key 多为字符串, 但也有时我们需要对象或者数组作为键名的时候,
Object.prototype.toString.call({}) // '[object Object]'
Object.prototype.toString.call(new WeakMap()) // '[object WeakMap]'
可以看到使用 Object.prototype.toString.call()方法对 对象{} 和 new WeakMap()进行判断, 结果 显示两者还是有所不同的
这时候就有两个数据结构 Map 和 WeakMap. 今天主要来学习 WeakMap.
回顾 Map 类(映射)
Map 用于创建一个映射对象, 来存储键名/值映射
let map = new Map() // 这里的 new 创建一个映射对象, 用于键 / 值映射
WeakMap类 (弱映射)
WeakMap 弱映射, 主要用于实现值与对象的关联而不导致内存泄漏. 如下解释:
WeakMap 结构与 Map 结构类似,也是用于生成键值对的集合。但是 WeakMap 只接受对象作为键名( null 除外),不接受其他类型的值作为键名。而且 WeakMap 的键名所指向的对象,不计入垃圾回收机制。
在 Vue3 源码的时候, 我们会见到这个关键字 WeakMap
// 首先我们要设置两个缓存
let toProxy = new WeakMap() // 根据原始数据查询响应后的数据
let toRaw = new WeakMap() // 根据响应后的数据查询原始数据
然后在进行响应式数据的编写时,对缓存进行查询,已减少不必要的性能消耗
这里的 target 即是要进行响应式的对象, 通过 WeakMap 进行数据缓存
function reactive(target) {
// 查询缓存
let observed = toProxy.get(target)
if (observed) {
return observed
}
if (toRaw.get(target)) {
return target
}
// 响应式
observed = new Proxy(target, baseHandler)
// 设置缓存
toProxy.set(target, observed)
toRaw.set(observed, target)
return observed
}