zoukankan      html  css  js  c++  java
  • Proxy

    defineProperty的问题

    虽然Object.defineProperty能够劫持对象的属性,但是需要对对象的每一个属性进行遍历劫持;如果对象上有新增的属性,则需要对新增的属性再次进行劫持;如果属性是对象,还需要深度遍历。这也是为什么Vue给对象新增属性需要通过$set的原因,其原理也是通过Object.defineProperty对新增的属性再次进行劫持。
    Object.defineProperty除了能够劫持对象的属性,还可以劫持数组;虽然数组没有属性,但是我们可以把数组的索引看成是属性:

     虽然我们监听到了数组中元素的变化,但是和监听对象属性面临着同样的问题,就是新增的元素并不会触发监听事件,除此之外,直接修改数组的length属性也会导致Object.defineProperty的监听失败。

    为此,Vue的解决方案是劫持Array.property原型链上的7个函数,我们通过下面的函数简单进行劫持:

    Proxy

    相较于Object.defineProperty劫持某个属性,Proxy则更彻底,不在局限某个属性,而是直接对整个对象进行代理。

    ES6中对Proxy的描述为:Proxy可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。

    Proxy本身是一个构造函数,通过new Proxy生成拦截的实例对象,让外界进行访问;构造函数中的target就是我们需要代理的目标对象,可以是对象或者数组;handlerObject.defineProperty中的descriptor描述符有些类似,也是一个对象,用来定制代理规则。

    可以看到Proxy直接代理了target整个对象,并且返回了一个新的对象,通过监听代理对象上属性的变化来获取目标对象属性的变化;而且我们发现Proxy不仅能够监听到属性的增加,还能监听属性的删除,比Object.defineProperty的功能更为强大。

     不管是数组下标或者数组长度的变化,还是通过函数调用,Proxy都能很好的监听到变化;而且除了我们常用的get、set,Proxy更是支持13种拦截操作。

    可以看到Proxy相较于Object.defineProperty在语法和功能上都有着明显的优势;而且Object.defineProperty存在的缺陷,Proxy也都很好地解决了。
     
  • 相关阅读:
    springboot动态修改日志级别
    加密算法之RSA算法
    关于 BeanDefinitionOverrideException的解析
    Hive基础知识总结
    Java中的字符串替换:replace/replaceAll/StringTemplate
    xxl-job简介&整体架构设计
    java启动springboot jar包后台不挂断运行
    java自定义线程名称
    idea2019.2.2版本激活
    Log4j的MDC机制如何在线程池中使用
  • 原文地址:https://www.cnblogs.com/yuyujuan/p/14235615.html
Copyright © 2011-2022 走看看