weakMap
只接受对象作为键名
键名所引用的对象是弱引用,不可遍历(可能在任何时刻被垃圾回收器回收)利用这一特征,在对数据量很大的时候就可做一部分的优化
例子: Vue3在 检测到哪些数据发生了变化时候用了weakMap。所以当我们需要关联对象和数据,比如在不修改原有对象的情况下储存某些属性或者根据对象储存一些计算的值等,但是又不想管理这些数据的死活时可以考虑使用 WeakMap
const targetMap = new WeakMap<any, KeyToDepMap>()
export function track(target: object, type: TrackOpTypes, key: unknown) {
if (!shouldTrack || activeEffect === undefined) {
return
}
let depsMap = targetMap.get(target)
if (!depsMap) {
targetMap.set(target, (depsMap = new Map()))
}
let dep = depsMap.get(key)
if (!dep) {
depsMap.set(key, (dep = new Set()))
}
if (!dep.has(activeEffect)) {
dep.add(activeEffect)
activeEffect.deps.push(dep)
if (__DEV__ && activeEffect.options.onTrack) {
activeEffect.options.onTrack({
effect: activeEffect,
target,
type,
key
})
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
new weakSet
const seen = new WeakSet()
export const transformOnce: NodeTransform = (node, context) => {
if (node.type === NodeTypes.ELEMENT && findDir(node, 'once', true)) {
if (seen.has(node)) {
return
}
seen.add(node)
context.helper(SET_BLOCK_TRACKING)
return () => {
const cur = context.currentNode as ElementNode | IfNode | ForNode
if (cur.codegenNode) {
cur.codegenNode = context.cache(cur.codegenNode, true /* isVNode */)
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Reflect
内置的对象。F12可以在控制台打印出来
让Object 操作变成函数行为 ,并且与new Proxy相对应(set, get)
function deleteProperty(target: object, key: string | symbol): boolean {
const hadKey = hasOwn(target, key)
const oldValue = (target as any)[key]
const result = Reflect.deleteProperty(target, key)
if (result && hadKey) {
trigger(target, TriggerOpTypes.DELETE, key, undefined, oldValue)
}
return result
}
function has(target: object, key: string | symbol): boolean {
const result = Reflect.has(target, key)
if (!isSymbol(key) || !builtInSymbols.has(key)) {
track(target, TrackOpTypes.HAS, key)
}
return result
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
处理new Proxy get时对应函数
function createGetter(isReadonly = false, shallow = false) {
return function get(target: Target, key: string | symbol, receiver: object) {
if (key === ReactiveFlags.IS_REACTIVE) {
return !isReadonly
} else if (key === ReactiveFlags.IS_READONLY) {
return isReadonly
} else if (
key === ReactiveFlags.RAW &&
receiver === (isReadonly ? readonlyMap : reactiveMap).get(target)
) {
return target
}
const targetIsArray = isArray(target)
if (targetIsArray && hasOwn(arrayInstrumentations, key)) {
return Reflect.get(arrayInstrumentations, key, receiver)
}
const res = Reflect.get(target, key, receiver)
if (
isSymbol(key)
? builtInSymbols.has(key as symbol)
: key === `__proto__` || key === `__v_isRef`
) {
return res
}
if (!isReadonly) {
track(target, TrackOpTypes.GET, key)
}
if (shallow) {
return res
}
if (isRef(res)) {
// ref unwrapping - does not apply for Array + integer key.
const shouldUnwrap = !targetIsArray || !isIntegerKey(key)
return shouldUnwrap ? res.value : res
}
if (isObject(res)) {
// Convert returned value into a proxy as well. we do the isObject check
// here to avoid invalid value warning. Also need to lazy access readonly
// and reactive here to avoid circular dependency.
return isReadonly ? readonly(res) : reactive(res)
}
return res
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
Reflect.defineProperty方法基本等同于Object.defineProperty,用来为对象定义属性, Object.defineProperty在之后会被逐渐废弃掉
————————————————
版权声明:本文为CSDN博主「青梅煮酒论英雄」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/this_tall_people/article/details/109579251