美文网首页
响应式框架原理3(Object.defineProperty V

响应式框架原理3(Object.defineProperty V

作者: nomooo | 来源:发表于2020-03-04 08:38 被阅读0次

    响应式框架原理2(数据劫持与代理-监听数组变化)
    继续之前的记录、、
    使用 Proxy 来完成代码重构:

                let data = {
                    stage: '状态',
                    course: {
                        title: '标题',
                        author: ['作者1', '作者2'],
                        publishTime: '出版时间'
                    }
                }
    
                const observe = data => {
                    if (!data || Object.prototype.toString.call(data) !== '[object Object]') {
                        return
                    }
    
                    Object.keys(data).forEach(key => {
                        let currentValue = data[key]
                        // proxy 也可以对函数类型进行代理。这里只对承载数据类型的 object 进行处理
                        if (typeof currentValue === 'object') {
                            observe(currentValue)
                            data[key] = new Proxy(currentValue, {
                                set(target, property, value, receiver) {
                                    // 因为数组的 push 会引起 length 属性的变化,所以 push 之后会触发两次 set 操作,只需要保留一次即可,property 为 length 时,忽略
                                    if (property !== 'length') {
                                        console.log(`setting ${key} value now, setting value is`, currentValue)
                                    }
                                    return Reflect.set(target, property, value, receiver)
                                }
                            })
                        } else {
                            Object.defineProperty(data, key, {
                                enumerable: true,
                                configurable: false,
                                get() {
                                    console.log(`getting ${key} value now, getting value is:`, currentValue)
                                    return currentValue
                                },
                                set(newValue) {
                                    currentValue = newValue
                                    console.log(`setting ${key} value now, setting value is`, currentValue)
                                }
                            })
                        }
                    })
                }
                observe(data)
    

    对数组操作:

                data.course.author.push('作者3')
    

    上面代码在使用proxy进行代理时,并没有对getter进行代理,所以输出结果不会有getting value输出
    使用 Object.defineProperty;对于键值为对象类型的情况,继续递归调用 observe 方法,并通过 Proxy 返回的新对象对 data[key] 重新赋值,这个新值的 getter 和 setter 已经被添加了代理。

    结合上两篇笔记,对 Proxy 实现数据代理和 Object.defineProperty 实现数据拦截进行对比:

    • Object.defineProperty 不能监听数组的变化,需要进行数组方法的重写

    • Object.defineProperty 必须遍历对象的每个属性,且对于嵌套结构需要深层遍历

    • Proxy 的代理是针对整个对象的,而不是对象的某个属性,因此不同于 Object.defineProperty 的必须遍历对象每个属性,Proxy 只需要做一层代理就可以监听同级结构下的所有属性变化,当然对于深层结构,递归还是需要进行的

    • Proxy 支持代理数组的变化

    • Proxy 的第二个参数除了 set 和 get 以外,可以有 13 种拦截方法,比起 Object.defineProperty() 更加强大 Proxy与Reflect

    • Proxy 性能将会被底层持续优化,而 Object.defineProperty 已经不再是优化重点

    相关文章

      网友评论

          本文标题:响应式框架原理3(Object.defineProperty V

          本文链接:https://www.haomeiwen.com/subject/rkwflhtx.html