/* 对数组的一些API进行跟进 */ 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) // 我们首先使用原始参数运行该方法(这可能是 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) // 仪器改变长度的突变方法以避免长度被跟踪 // 在某些情况下会导致无限循环 (#2137) ;(['push', 'pop', 'shift', 'unshift', 'splice'] asconst).forEach(key => { instrumentations[key] = function (this: unknown[], ...args: unknown[]) { pauseTracking() // 依赖处理相关API const res = (toRaw(this) asany)[key].apply(this, args) resetTracking() return res } }) return instrumentations }
/* 内部涉及到的函数 */
// 直接调用 createGetter,并且入参都是默认入参 const get = /*#__PURE__*/createGetter()
// 从这里可以看出,对于多纬JSON或数组并不是一开始就转换为代理。只有在读取到的时候才进行转换 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. // 也将返回值转换为代理。 我们做 isObject 检查 // 这里是为了避免无效值警告。 还需要延迟访问只读 // 并在这里反应以避免循环依赖。 // 这里就是如果是对象,就有递归处理将对象处理成代理 // 因为`proxy`API虽然比`Object.defineProperty`强大,但是它也只代理当前一层的对象,对于嵌套对象是不会自动深层代理的 // 需要代码递归处理 return isReadonly ? readonly(res) : reactive(res) }
// 这里在单独拿出来看一下 // ...other code else { // in shallow mode, objects are set as-is regardless of reactive or not // 在浅层模式下,无论是否reactive,对象都按原样设置 } // ...other code