- 我们在建立观察者的时候,没有考虑数据是数组的情况,如果数据是数组,按照之前的逻辑,会将数组以索引为属性名进行劫持,这样对性能并不高,我们不考虑对数组索引进行劫持,而只封装数组的方法
- 建立观察者时,添加对数组的判断
- 若为数组,则分流进行下一步操作
- 重建数组父类,重新添加数组方法
- 若数组里面的值为对象,则应该监听
- 遍历数组,对值调用观察者
- 数组可以通过封装的方法来追加对象,应该对追加的内容进行监听
- 在数组上追加属性,指向观察者实例
- 判断数组追加内容,通过该属性,调用观察者
- 若为数组,则分流进行下一步操作
- 建立观察者时,添加对数组的判断
- 观察者类更改
-
constructor(data){ // data.__po__ = this; Object.defineProperty(data,'__po__',{ value:this, enumerable:false }) if(Array.isArray(data)){ data.__proto__ = arrayMethods; this.observeArray(data); } else { //对对象中的所有属性进行劫持 this.walk(data); } } // 如果数组中包含对象,则再次被监控 observeArray(data){ data.forEach(item =>{ observe(data); }) }
新建arrat.js
-
let oldArrayPrototype = Array.prototype; export let arrayMethods = Object.create(oldArrayPrototype); let methods = [ 'push', 'shift', 'unshift', 'pop', 'reverse', 'sort', 'splice' ] methods.forEach(method =>{ arrayMethods[method] = function(...args){ console.log('数组改变了'); oldArrayPrototype[method].call(this,...args); // 通过push、unshift、splice方法也可能对数据进行更改 let po = this.__po__; let inserted; switch (method) { case 'push': case 'unshift': inserted = args; break; case 'splice': inserted = args.slice(2); break; } if(inserted) { po.observeArray(inserted); } } })
手撕Vue源码(三)数组数据劫持
最新推荐文章于 2022-05-16 16:57:18 发布