递归侦测对象

119 阅读1分钟

下图的基本的原理就是函数先判断有没有__ob__,没有就new Observer类,此时就加上__ob__,然后就遍历下一层属性,如果还是对象就继续observe函数,此时有__ob__就直接遍历下一层看看还是不是对象,直到不是对象,三个函数之间递归遍历,实现数据的侦测。 image.png 主要将其封装为四个文件,除了index.js,其他三个文件进行递归

image.png

首先创建一个observe函数判断是不是对象,再判断是不是有__ob__这个属性

// 创建obServe函数
function obServe(value){
    // 判断是不是对象
    if(typeof value !='object') return
    var ob
    // 判断是有没有value.__ob__
    if(typeof value.__ob__ !=='undefined'){
        ob = value.__ob__
    }else{
        ob = new Observer(value)
    }

    return ob
}

创建一个Observer类,给对象添加__ob__这个属性

import { def } from "./utils";
export default class Observer{
    constructor(value){
        // 构造函数的this不是类本身,是构建的实例,给this添加的__ob__这个属性,值是这次new的实例
        def(value,'__ob__',this,false)
        console.log('Observer构造器',value);
    }
}

添加一个工具函数,进行递归

export const def = function (obj,key,value,enumertable){//将其this赋值到value
    Object.defineProperty(obj,key,{
        value,
        enumertable,
        writable:true,
        configurable:true
    })
}

将其对象赋值给val进行遍历

import observe from "./observe"

export default function defineReactive(data, key, val) {
    console.log('defineReactive', data,key)
    //如果参数为两个就将其对象的属性赋值给val
    if (arguments.length == 2) {
        val = data[key]
    }

    // 三个函数形成递归
    let childObj = observe(val)

    Object.defineProperty(data, key, {
        enumerable: true,
        configurable: true,
        get() {
            console.log('访问' + key + '属性')
            return val
        },
        set(newValue) {
            console.log('改变' + key + '属性',newValue)
            if (val === newValue) {
                return
            }
            val = newValue
            // 将其里面的对象重新赋值给子对象,进行递归
            childObj = observe(newValue)
        }
    })
}