美文网首页
数组如何进行劫持和观测

数组如何进行劫持和观测

作者: JX灬君 | 来源:发表于2021-08-17 00:04 被阅读0次

    数组如何进行劫持和观测

    对数组[{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后劫持

    • 假如data里有个数组arr = [{a:1}],通过push追加上之后vm.data.arr.push({b:2})
      新追加的b没有被劫持。
    • 如何让新追加的数组也被劫持?(需要继承改造Array方法)
     // 判断三种追加方式 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  // 指向当前实例
    })
    
    • observeArray 方法
    obserArray(value) {
            //进行循环
            value.forEach(item => {
                Observer(item)
            })
        }
    
    • Observer方法
    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)
    }
    
    • 完整的observe类
    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 中有的
            })
        }
    }
    

    相关文章

      网友评论

          本文标题:数组如何进行劫持和观测

          本文链接:https://www.haomeiwen.com/subject/eozvbltx.html