if (!isReadonly) { if (targetIsArray && hasOwn(arrayInstrumentations, key)) { returnReflect.get(arrayInstrumentations, key, receiver) } if (key === 'hasOwnProperty') { return hasOwnProperty } }
const res = Reflect.get(target, key, receiver)
if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) { return res }
if (!isReadonly) { track(target, TrackOpTypes.GET, key) }
if (shallow) { return res }
if (isRef(res)) { // ref unwrapping - skip unwrap for Array + integer key. return targetIsArray && isIntegerKey(key) ? res : res.value }
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 } }
const set = /*#__PURE__*/createSetter() const shallowSet = /*#__PURE__*/createSetter(true)
functioncreateArrayInstrumentations() { constinstrumentations: Record<string, Function> = {} // instrument identity-sensitive Array methods to account for possible reactive // values ;(['includes', 'indexOf', 'lastIndexOf'] asconst).forEach(key => { instrumentations[key] = function (this: unknown[], ...args: unknown[]) { const arr = toRaw(this) asany 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 } } }) // instrument length-altering mutation methods to avoid length being tracked // which leads to infinite loops in some cases (#2137) ;(['push', 'pop', 'shift', 'unshift', 'splice'] asconst).forEach(key => { instrumentations[key] = function (this: unknown[], ...args: unknown[]) { pauseTracking() const res = (toRaw(this) asany)[key].apply(this, args) resetTracking() return res } }) return instrumentations }
在完成了类数组的劫持后, const res = Reflect.get(target, key, receiver) 通过反射获取本应该取到的值。
接下来 if (isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) {
1 2 3 4 5 6 7 8 9 10 11 12
const builtInSymbols = newSet( /*#__PURE__*/ Object.getOwnPropertyNames(Symbol) // ios10.x Object.getOwnPropertyNames(Symbol) can enumerate 'arguments' and 'caller' // but accessing them on Symbol leads to TypeError because Symbol is a strict mode // function .filter(key => key !== 'arguments' && key !== 'caller') .map(key => (Symbolasany)[key]) .filter(isSymbol) )
if (!isReadonly) { track(target, TrackOpTypes.GET, key) }
if (shallow) { return res }
if (isRef(res)) { // ref unwrapping - skip unwrap for Array + integer key. return targetIsArray && isIntegerKey(key) ? res : res.value }
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
接下来就是判断和追踪,定义其他的返回或者返回的包装。
重新回顾一下,这个方法做了什么
判断 key IS_REACTIVE or IS_READONLY or IS_SHALLOW 返回对应值