Proxy和Object.defineProperty的区别
- Vue2.x 通过给每个对象添加getter setter属性去改变对象,实现对数据的观测,Vue3.x 通过 Proxy 代理目标对象,且一开始只代理最外层对象,嵌套对象lazy by default ,性能会更好
- proxy支持数组索引修改,对象属性的增加,删除
Vue 在实例初始化时遍历 data 中的所有属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。这样当追踪数据发生变化时,setter 会被自动调用。Object.defineProperty 是 ES5 中一个无法声明的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。
但是这样做有以下问题:
- 添加或删除对象的属性时,Vue 检测不到。因为添加或删除的对象没有在初始化进行响应式处理,只能通过$set 来调用Object.defineProperty()处理。
- 无法监控到数组下标和长度的变化。
Vue3 使用 Proxy 来监控数据的变化。Proxy 是 ES6 中提供的功能,其作用为:用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。相对于Object.defineProperty(),其有以下特点:
- Proxy是对整个对象的代理,而Object.defineProperty只能代理某个属性。
- 对象上新增属性,Proxy可以监听到,Object.defineProperty不能。
- 数组新增修改,Proxy可以监听到,Object.defineProperty不能。
- 若对象内部属性要全部递归代理,Proxy可以只在调用的时候递归,而Object.definePropery需要一次完成所有递归,性能比Proxy差。
- Proxy不兼容IE,Object.defineProperty不兼容IE8及以下
- Proxy使用上比Object.defineProperty方便多。