Object.defineProperty 的实际应用

此前在看尤大大的视频时对其介绍vue Object.defineProperty属性方法的一些尝试,再次将其方法搬出来同时加一些自己的注解。也许代码备注有所错误,请大佬指出。

<script>
         // 尝试双向数据绑定

        // 首先定义一个方法用来数据劫持
        function observe(obj) {
            // 判断是否为obj
            if (!isObject(obj)) {
                // 抛出错误
                throw new TypeError()
            }
            // 在这里对obj进行循环
            // 因为Object.defineProperty需要对key值进行监听
            Object.keys(obj).forEach(key => {
                // 创建一个内部变量
                let internalValue = obj[key]

                // 创建一个dep 实例
                let dep = new Dep()
                // 使用Object.defineProperties 进行数据监听
                // 在这里对gei 和set 方法进行重构
                Object.defineProperty(obj, key, {
                    // 获取数据并返回
                    get() {

                        dep.depend()
                        console.log(activeUpdate,'更新状态activeUpdate');
                        // 将获取到的数据进行返回
                        return internalValue
                    },
                    // 设置数据
                    set(newValue) {
                        console.log(newValue,'改变的值newValue');
                        const isChanged = internalValue !== newValue
                        if (isChanged) {
                            internalValue = newValue
                            dep.notify()
                        }
                    }
                })
            })
        }

        // 在这里对dep进行声明创建

        window.Dep = class Dep {
            constructor() {
                // 声明一个变量 订阅者
                this.subscribers = new Set()
            }
            // 同时此方法还应该有 依赖和通知

            depend() {
                // 通知判断状态
                if (activeUpdate) {
                    // 将当前活动更新注册为订阅者  
                    this.subscribers.add(activeUpdate)
                }
            }
            // 通知
            notify() {
                // 运行所有订阅函数
                console.log(this.subscribers,'所有的属性');
                this.subscribers.forEach(subscriber => {
                    subscriber()
                    console.log(subscriber,'方法');
                })
            }
        }

        let activeUpdate
        // 一个自动执行的方法
        function autorun(update) {
            function wrappedUpdate() {
                activeUpdate = wrappedUpdate
                // 再此调用 输入的方法也就是对响应式触发
                update()
                activeUpdate = null
            }
            wrappedUpdate()
        }

        // 一个判断是否为obj的方法
        function isObject(obj) {
            return typeof obj === 'object'
                && !Array.isArray(obj)
                && obj !== null
                && obj !== undefined
        }

        // 定义一个对象
        let state = {
            count: 0
        }
        
        /**当执行这个方法时,会首先判断是否为obj 如果是则对state 键值对(属性名)进行循环
         *然后为每个属性名创建一个dep class 然后用 object.defineProperty进行监听
         本质上当调用或者修改当前数据的时候都会进行监听,这也就是为什么activeUpdate 存在的必要
         defineProperty 方法 首先会在get方法也就是获取值的时候 调用 depend方法 将参数注册到订阅者里
        同时在set 方法时判断数据是否改变同时通知notify 来进行操作 也就是运行 autorun 方法即自动执行
          
        
        **/
        observe(state)

        autorun(() => {
            window.console.log(`count is: ${state.count}`)
        })
        // console.log(state.count);
        state.count++
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值