利用 proxy 监视对象的变化

vue 对于 mvvm 的实现是基于 Object.defineProperty 来实现的,
对于 es6 而言有另外一种类似的监视对象属性变化的 api, 即使用代理 Proxy

对于这个 api 不熟悉的开发者可以点击这里

利用 porxy 代理对象的 get, defineProperty, deleteProperty
方法即可实现,代码简洁明了

const watch = (object, onChange) => {
   const handler = {
       /*  
           如果 target[property] 为对象时递归代理,否则返回属性值
           @param {object} target
           @param {string} property
           @param {object} [receiver]
       */
       get (target, property, receiver) {
           try {
               return new Proxy(target[property], handler)
           } catch (err) {
               return Reflect.get(target, property, receiver)
           }
       },
       
       /*
           当对象赋值的时候,触发的代理方法(如果有 set 代理, 则触发 set 代理,否则触发该方法)
           @param {object} target
           @param {string} property
           @param {object} descriptor
       */
       defineProperty (target, property, descriptor) {
           onChange() // 赋值时触发回调函数
           return Reflect.defineProperty(target, property, descriptor)
       },
       
       /*
           当删除对象属性时触发的代理方法
           @param {object} target
           @param {string} property
       */
       deleteProperty (target, property) {
           onChange() // 删除属性时触发回调函数
           return Reflect.deleteProperty(target, property)
       }
   }
   
   return new Proxy(object, handler)
}

// demo
let obj = {
   a: 123,
   b: {
       c: 333
   }
}
let i = 0
let watchObj = watch(obj, () => {console.log('Object changed:', ++i)})
watchObj.a = 333
// => 'Object changed: 1'
watchObj.b.c = 444
//=> 'Object changed: 2'

参考链接

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容