js深度监听对象的变化

这篇博客介绍了如何使用JavaScript的Object.defineProperty方法深度监听对象属性的变化,包括内部嵌套的对象和数组。通过一个名为DataBroker的函数,实现了递归监听并确保在数据变更时执行回调函数。示例展示了监听一个包含嵌套对象和数组的复杂对象,并在数据改变时触发回调。注意,对于监听的数组,只能使用特定API(如push等)进行操作以保证监听生效。
摘要由CSDN通过智能技术生成

js深度监听对象的变化

众说周知,对对象进行属性的监听要使用 Object.defineProperty这个方法,如果不知道请先去了解一下。

  • 我们使用 Object.defineProperty监听一层对象时是非常简单的,但难在如何监听更深的对象,比如对象中有个属性值是对象,对象中又有个属性值又是对象,这种监听就有一点难度了,咱们废话不多说直接上代码

下面这个函数就能实现对对象的深度监听,方法中有三个参数

  1. object 是一个你需要提前准备的空对象,它用来接收要监听的对象
  2. value 是你要监听的对象,对象的值最后会放在 你传给 object 的对象
  3. fun 是一个回调当监听对象中数据发生改变时就会调用
let DataBroker = function (object, value, fun) {
        function ArrayBroker(arr, fun) {
            let newPrototype = Object.create(Array.prototype);
            let methods = ["push", "pop", "shift", "unshift", "reverse", "sort", "splice"];
            methods.forEach(method => {
                newPrototype[method] = function (...args) {
                    //! 关键部分 我们使用延时定时器将函数调用由同步变为异步操作
                    //! 这步是为了让对数组的的操作先执行,在执行函数的调用
                    setTimeout(function () {
                        fun();
                    }, 0);
                    return Array.prototype[method].call(this, ...args);
                };
            });
            arr.__proto__ = newPrototype;
            //判断数组中是否有对象和数组如果有进行get set和数组监听
            for (let i = 0; i < arr.length; i++) {
                if (arr[i] instanceof Array) {
                    ArrayBroker(arr[i], fun);
                } else if (arr[i] instanceof Object) {
                    let temp = arr[i];
                    arr[i] = new Object();
                    DataBroker(arr[i], temp, fun);
                }
            }
        };
        for (let i in value) {
            if (value[i] instanceof Array) {
                //!         防止对原数组的更改
                object[i] = [...value[i]];
                ArrayBroker(object[i], fun);
            } else if (value[i] instanceof Object) {
                let obj = new Object();
                object[i] = obj;
                DataBroker(object[i], value[i], fun);
            } else {
                Object.defineProperty(object, i, {
                    enumerable: true,
                    get() {
                        return value[i];
                    },
                    set(val) {
                        value[i] = val;
                        fun();
                    }
                });
            };
        };
        fun();
    };

示例

    //定义一个空对象
    let _data = {};
    DataBroker(_data, {
        //需要监听的对象
        name: '张三',
        adg: 30,
        user: {
            name: '李四',
            adg: 20,
            arr:['0','1','2']
        }
    }, function () {
        //回调函数
        console.log('数据发送改变');
    });

修改对象中是数据

  • 修改对象中是数据,监听到数据的改变,调用回调函数

数据中如果有数组的话只能使用以下API操作数组才能实现监听

  • push(), pop(), shift(), unshift(), reverse(), sort(), splice()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值