arrayInstrumentations主要是改寫數(shù)組的方法
1.改寫includes骑晶、indexOf配深、lastIndexOf這三個(gè)方法兆蕉。這三個(gè)方法無法'準(zhǔn)確'追蹤數(shù)組中元素昧穿。具體表現(xiàn)如下(案例來自網(wǎng)絡(luò))
const arr = reactive([2,1,3])
effect(() => {
console.log(arr.indexOf(2))
})
setTimeout(() =>{
arr[1] = 4
}, 5000)
當(dāng)修改arr[1]的值時(shí)厕妖,將會(huì)觸發(fā)副作用函數(shù)的的執(zhí)行第美,但arr[1]值的改變并不會(huì)影響副作用函數(shù)的結(jié)果(arr[0]不等于2時(shí)才影響)蝶锋,因此可以判定是無效的觸發(fā)。
因此當(dāng)調(diào)用的是這三個(gè)方法時(shí)什往,要對(duì)數(shù)組中的每個(gè)元素進(jìn)行依賴收集扳缕,這樣才能正確觸發(fā),這里還要注意處理參數(shù)已經(jīng)被proxy代理的情況
;(['includes', 'indexOf', 'lastIndexOf'] as const).forEach(key => {
instrumentations[key] = function (this: unknown[], ...args: unknown[]) {
const arr = toRaw(this) as any
for (let i = 0, l = this.length; i < l; i++) {
track(arr, TrackOpTypes.GET, i + '')
}
// we run the method using the original args first (which may be reactive)
const res = arr[key](...args)
if (res === -1 || res === false) {
// if that didn't work, run it again using raw values.
return arr[key](...args.map(toRaw))
} else {
return res
}
}
})
2.改寫push别威、pop躯舔、shift、unshift省古、splice這三個(gè)方法粥庄。這三個(gè)方法是直接調(diào)用數(shù)組對(duì)應(yīng)的方法,返回對(duì)應(yīng)的結(jié)果豺妓,不進(jìn)行額外的依賴收集
// instrument length-altering mutation methods to avoid length being tracked
// which leads to infinite loops in some cases (#2137)
;(['push', 'pop', 'shift', 'unshift', 'splice'] as const).forEach(key => {
instrumentations[key] = function (this: unknown[], ...args: unknown[]) {
pauseTracking()
const res = (toRaw(this) as any)[key].apply(this, args)
resetTracking()
return res
}
})
export function pauseTracking() {
trackStack.push(shouldTrack)
shouldTrack = false
}
export function resetTracking() {
const last = trackStack.pop()
shouldTrack = last === undefined ? true : last
}
為什么這么做呢惜互?從注釋中找到的信息是避免length改變陷入無盡的回調(diào)。那么如果此處不進(jìn)行依賴收集琳拭,那么依賴收集是在哪一塊進(jìn)行的呢载佳?讓我們回看上一章中mutableHandlers方法,此方法只是針對(duì)數(shù)組這八個(gè)方法進(jìn)行改寫臀栈,那么length屬性呢蔫慧,不在這當(dāng)中,還是繼續(xù)往下執(zhí)行权薯,會(huì)進(jìn)行依賴收集姑躲。因此如果這里再進(jìn)行依賴收集睡扬,那么就會(huì)重復(fù),因此不需要再進(jìn)行收集黍析。
下文主要對(duì)依賴收集函數(shù)track進(jìn)行展開卖怜!
本人菜雞,有問題望前輩及時(shí)指出阐枣,不勝感激B砜俊!