美文网首页
响应式框架原理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