02-将对象所有属性变为可侦测

02-将对象所有属性变为可侦测


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>

        // 通过定义1个类 Observer,使用循环递归的方式 将对象的所有属性变成可侦测属性
        class Observer {
            constructor(value) {
                this.value = value;
                if (Array.isArray(value)) {
                    // value是数组的时候,用数组的侦听方式
                } else {
                    // 当对象的时候调用walk实现侦测属性
                    this.walk(value);
                }
            }
            walk(obj) {
                const keys = Object.keys(obj)
                for (let i = 0; i < keys.length; i++) {
                    defineReactive(obj, keys[i])
                }
            }
        }
        function defineReactive(obj, key, val) {
            // 当只传入2个值的时候,可以直接获取到第三个参数value值
            if (arguments.length == 2) {
                val = obj[key]
            };

            // 如果属性的值value也是对象,那么也需要将其变为可侦测
            if (typeof val === 'object') {
                new Observer(val);
            };

            // Object.defineProperty 定义属性
            Object.defineProperty(obj, key, {
                enumerable: true, // 定义此属性出现在for-in循里面,以及Object.keys() 的遍历中
                configurable: true, // 定义此属性可以配置和删除
                // 取数据的描述符
                get() {
                    console.log(`读取属性: ${key}`);
                    return val // 获取
                },
                // 存数据的描述符
                set(newValue) {
                    if (val === newValue) {
                        return  // 相同不用做任何操作
                    } else {
                        console.log(`存储属性: ${key}`);
                        console.log('存入的数据:' + newValue);
                        val = newValue;// 值改变了
                    }
                }
            });

        }

        let user = {
            username: '江哥',
            type: '帅',
            friend: {
                username: '老王'
            }
        };
        new Observer(user)

    </script>

</body>

</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

前端酱紫

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

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

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

打赏作者

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

抵扣说明:

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

余额充值