Observe 源码解析 劫持Object对象 监听数据变化

/**
 * 可以帮我们事先对对象里面的所有属性进行劫持
 * */ 
class Observe{
    constructor(obj){
        this.observe(obj)
    }
    observe(obj){
        if(obj&&typeof obj=='object'){
            for(let attr in obj){
                this.defineReactive(obj,attr,obj[attr])
            }
        }
    }
    /**
     * obj待处理的对象
     * attr 对象的属性
     * value 进行get/set 操作的是value
     * */ 
    defineReactive(obj,attr,value){
        this.observe(value);//对value需要进一步的进行劫持
        Object.defineProperty(obj,attr,{
            get(){
                return value;
            },
            set:(newValue)=>{
                if(value!==newValue){
                    this.observe(newValue);//判断新设置的值是否是对象,如果是对象,也需要被劫持
                    value=newValue;
                    console.log('set操作,数据变化了,视图进行更新',newValue);
                }
            }
        })
    }
}
    <script>
        const obj={
            id:1,
            name:'andy',
            age:{
                n:23
            }
        }
       
        new Observe(obj)
        obj.age={
            n:50}
        obj.age.n=54
        console.log(obj);
    </script>

 代码解析 

1.constructor构造函数

 constructor(obj){
        this.observe(obj)
    }

是初始化Observe类,将所传入类的参数,可以通过constructor参数的obj中获取

这里的this是代表Observe这个类的this,调用这个类里面的observe方法

2.observe方法定义逻辑

    observe(obj){
        if(obj&&typeof obj=='object'){
            for(let attr in obj){
                this.defineReactive(obj,attr,obj[attr])
            }
        }
    }

是对象与数组劫持所以首先判断传入的类型,是否符合

通过for in的方式将,对象的key,value,对象遍历出来,循环调用defineReactive,将数据传入

3.数据劫持关键代码

 defineReactive(obj,attr,value){
        this.observe(value);//对value需要进一步的进行劫持
        Object.defineProperty(obj,attr,{
            get(){
                return value;
            },
            set:(newValue)=>{
                if(value!==newValue){
                    this.observe(newValue); 
                    value=newValue;
                    console.log('set操作,数据变化了,视图进行更新',newValue);
                }
            }
        })
    }

(1).先看Object.defineProperty

get是监听获取对象中值的时候,会执行

set是监听设置的时候会执行

为什么在set箭头函数内,再次调用this.observe是因为放置所设置的值是对象,若是对象则继续执行监听,不是则停止,observe有判断拦截

(2).一开始上来就先调用this.observe(value)

因为对象内也可以再声明对象,若没有再次以递归的方式调用一次,则无法监听,多个对象执行修改

如下:

new Observe(obj)
obj.age={n:50}
obj.age.n=54

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路光.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值