Object.defineProperty 与 proxy区别及缺点

1,904 阅读3分钟

Object.defineProperty 与 proxy区别及缺点

Object.defineProperty的缺陷:
1)无法检测到对象属性的新增或删除
    由于js的动态性,可以为对象追加新的属性或者删除其中某个属性,
    这点对经过Object.defineProperty方法建立的响应式对象来说,
    只能追踪对象已有数据是否被修改,无法追踪新增属性和删除属性,
    这就需要另外处理。
2)不能监听数组的变化(对数组基于下标的修改、对于 .length 修改的监测)
   vue在实现数组的响应式时,它使用了一些hack,
   把无法监听数组的情况通过重写数组的部分方法来实现响应式,
   这也只限制在数组的push/pop/shift/unshift/splice/sort/reverse七个方法,
   其他数组方法及数组的使用则无法检测到, 
解决方法主要是使用proxy属性,这个proxy属性是ES6中新增的一个属性,
    proxy属性也是一个构造函数,他也可以通过new的方式创建这个函数,
    表示修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种元编程
    proxy可以理解为在目标对象之前架设一层拦截,外界对该对象的访问,都必须经过这层拦截,
    因此提出了一种机制,可以对外界的网文进行过滤和改写,proxy这个词是代理,
    用来表示由他代理某些操作,可以译为代理器

    Proxy,字面意思是代理,是ES6提供的一个新的API,用于修改某些操作的默认行为,
    可以理解为在目标对象之前做一层拦截,外部所有的访问都必须通过这层拦截,
    通过这层拦截可以做很多事情,比如对数据进行过滤、修改或者收集信息之类。
    借用proxy的巧用的一幅图,它很形象的表达了Proxy的作用。
proxy代理的特点:
    proxy直接代理的是整个对象而非对象属性,
    proxy的代理针对的是整个对象而不是像object.defineProperty针对某个属性,
    只需要做一层代理就可以监听同级结构下的所有属性变化,
    包括新增的属性和删除的属性
proxy代理身上定义的方法共有13种,其中我们最常用的就是set和get,但是他本身还有其他的13种方法

proxy的劣势:
    兼容性问题,虽然proxy相对越object.defineProperty有很有优势,但是并不是说proxy,就是完全的没有劣势,主要表现在以下的两个方面:
        1)proxy有兼容性问题,无完全的polyfill:
            proxy为ES6新出的API,浏览器对其的支持情况可在w3c规范中查到,通过查找我们可以知道,
            虽然大部分浏览器支持proxy特性,但是一些浏览器或者低版本不支持proxy,
            因此proxy有兼容性问题,那能否像ES6其他特性有polyfill解决方案呢?,
            这时我们通过查询babel文档,发现在使用babel对代码进行降级处理的时候,并没有合适的polyfill
        2)第二个问题就是性能问题,proxy的性能其实比promise还差,
        这就需要在性能和简单实用上进行权衡,例如vue3使用proxy后,
        其对对象及数组的拦截很容易实现数据的响应式,尤其是数组

        虽然proxy有性能和兼容性处理,但是proxy作为新标准将受到浏览器厂商重点持续的性能优化,
        性能这块会逐步得到改善