数组如何进行劫持和观测

2021-08-17  本文已影响0人  JX灬君

数组如何进行劫持和观测

对数组[{a:1}]进行劫持

// value = [{a:1}]
observeArray(value){
  for(let i = 0; i < value.length; i++){
    // 将数组里的内容{a:1}丢给observe函数进行劫持
    observer(value[i]) // 劫持之后,a有了get和set方法
  }
}

对数组进行追加push后劫持

 // 判断三种追加方式 push,unshift,splice
let inserted
  switch(item){ 
     case 'push':
     case 'unshift':
       inserted = args
        break;
     case 'splice':
        inserted = args.splice(2)
        break;
  }
  // 获取__ob__属性
  let ob = this.__ob__
  // 判断有没有值
  if(inserted){
    ob.observeArray(inserted) // 对我们添加的对象进行劫持
  }
  return result
  
//获取data时,给data每个值定义一个属性
Object.defineProperty(data,'__ob__',{
  enumerable:false, // 不可枚举
  value:this  // 指向当前实例
})
obserArray(value) {
        //进行循环
        value.forEach(item => {
            Observer(item)
        })
    }
export function Observer(data) {
    // data 我们需要进行判断 typeof  object null
    //不能不是对象 并且不是null
    if (typeof data !== 'object' || data == null) {
        return;
    }
    //判断用户是否已经观测
    if(data.__ob__){
        return data;
    }
    //对这个是数据进行劫持 我们通过一个类
    return new observe(data)
}
class observe {
    constructor(value) {
        //1 给所有的对象类型添加一个dep 属性
        this.dep = new Dep() // 注意 (1){}  (2) [] 不是给里面属性添加dep
        // console.log(data)
        //使用defineProperty 重新定义属性 作用用来观测数据已经劫持过来
          //判断一个对象是否被观察过看他有没有 __ob__这个属性
          console.log(value);
          Object.defineProperty(value,"__ob__",{
           enumerable:false, //不能枚举
           configurable:false,
           value:this
          })

        if (Array.isArray(value)) { //注意对数组中的数据进行劫持 方法 劫持 修改数据的方法
            //我希望调用push  shift unshift splice sort reverse pop 这七个方法,那么我们就可以对
            //你这个方法进行劫持
            // 函数劫持,切片编程 []._ 
            value.__proto__ = arrayMethods // 对象__proto__属性:
            //监听数组中的值时对象
            this.obserArray(value)
        } else {
            this.walk(value)
        }

    }
    obserArray(value) {
        //进行循环
        value.forEach(item => {
            Observer(item)
        })
    }
    walk(data) { //数据是对象的的{a:{b:{}}}
        //循环
        let keys = Object.keys(data) //获取对象的key  注意这个key 只是 对象的最外层的
        keys.forEach(item => {
            defineReactive(data, item, data[item]) //Vue.util 中有的
        })
    }
}
上一篇 下一篇

猜你喜欢

热点阅读