<-Home

Vue 数据劫持代理

通过 Object.defineProperty() 方法设置属性的 setter 与 getter 方法,从而达到劫持 student 对象中的 name 属性的读取和设置操作的目的。

  • value: 该属性的值;
  • writable: 仅当值为 true 时表示该属性可以被改变;
  • get: getter (读取器);
  • set: setter (设置器);
  • configurable: 仅当值为 true 时,该属性可以被删除以及属性描述符可以被改变;
  • enumerable: 仅当值为 true 时,该属性可以被枚举。

需要注意的问题

  1. 属性描述符 - configurable
    • 可能该属性在此之前已经通过 Object.defineProperty() 方法设置了 configurable 的值;
    • 通过 Object.seal() 方法设置该对象为密封对象,只能修改该属性的值并且不能删除该属性以及修改属性的描述符;
    • 通过 Object.freeze() 方法冻结该对象,相比较 Object.seal() 方法,它更为严格之处体现在不允许修改属性的值。
  2. 默认 getter 和 setter 方法

  3. 递归问题

针对Array 的数据劫持

针对特殊方法做劫持,然后设置当前数组对象的原型,defineProperty本身能针对数组做劫持监听,只是考虑到性能问题没有选择使用

使用Proxy代替defineProperty

  1. 后者只能劫持对象的属性,而Proxy是直接代理对象
  2. 后者新增的属性需要重新手动尽心Observe操作
  3. Proxy支持13种拦截操作
  4. get,set,constructor,apply,has,deleteProperty,ownKeys,defineProperyt,getOwnPropertyDescription,..
  5. 但是有个明显的问题是目前Proxy的兼容性不如defineProperty,不过Proxy已经是标准,后续支持标准是各个浏览器会继续做的事情,指日可待