Object.defineProperty和Proxy对比

2020-11-12  本文已影响0人  书虫和泰迪熊

前言:大家都是到Vue2.0 的双向绑定是通过 Object.defineProperty 来劫持对象的setter 和 getter 方法来实现的。但是呢,,,,
对于对象

  1. Object.defineProperty 无法检测到 对象的添加或者移除,由于 Vue 会在初始化实例时对 property 执行 getter/setter 转化,所以 property 必须在 data 对象上存在才能让 Vue 将它转换为响应式的。
var vm = new Vue({
  data:{
    a:1
  }
})
// `vm.a` 是响应式的
vm.b = 2
// `vm.b` 是非响应式的

对于已经创建的实例,Vue 不允许动态添加根级别的响应式 property。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式 property

Vue.set(vm.someObject, 'b', 2)

您还可以使用 vm.$set 实例方法,这也是全局 Vue.set 方法的别名:

this.$set(this.someObject,'b',2)
  1. 对于如下 people 对象,如果用 Object.defineProperty 就得遍历people逐个绑定,需要绑定4次,这样很不方便,而用proxy 可以劫持整个对象。
const people = {
        name: 'Jim',
        sex:'男',
        height:'180',
        married:'yes'
}
const handler = {
        get: (obj, prop) => {
            console.log(obj[prop])
        },
        set : (obj, prop) => {
            console.log(obj[prop])
        }
    }
    const target = new Proxy(people, handler);

对于数组
Object.defineProperty 无法监控到数组下标的变化,比如:

  1. 当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
  2. 当你修改数组的长度时,例如:vm.items.length = newLength
    为了解决这个问题 Vue2.0 内部通过重写数组的8个方法来监听数组。但是指针对着8 个方法有一定的局限性。

所以Vue 3.0 使用了Proxy。。。。。。
具体使用参考官方文档 或者 https://www.jianshu.com/p/bd53624f1a86
</br>

对比

Proxy 优势如下

  1. Proxy 可以直接监听对象而非属性;
  2. Proxy 可以直接监听数组的变化;
  3. Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是Object.defineProperty 不具备的;
  4. Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改;
  5. Proxy 作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利;

Object.defineProperty 的优势如下:

兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平,因此 Vue 的作者才声明需要等到下个大版本( 3.0 )才能用 Proxy 重写。

上一篇下一篇

猜你喜欢

热点阅读