美文网首页
ES6 Proxy和Reflect

ES6 Proxy和Reflect

作者: 小路_7bb8 | 来源:发表于2020-08-28 17:01 被阅读0次

    前言:

    ES6一直在改进之前版本的一些写法,比如Promise,async/await,Proxy,Reflect等设计在实现老功能的基础上优化了写法。
    最近学习Vue3,真正学习了Proxy,以前只是知道有这么个写法。

    Proxy的用法:

    用于修改某些操作的默认行为,代理新的写法。
    语法如下:
    const person = {name: 'xiaolu',age: 'secret'}
    const handle = {
    get: function(target,key,property) {},
    set: function(target,key,property) {}
    }
    let proxyPerson = new Proxy(person,handler); // data是要代理的对象,handler是代理的操作对象的方法
    热门应用:
    优化Vue3的响应式
    如我们所知,Vue2的响应式其实存在一些缺点,比如需要深度监听,一次性递归到底,计算量大,无法监听新增和删除的属性,无法监听数组的新增和删除方法,Proxy可以优化这些缺点,但Proxy也有不足,它的兼容性并不是特别好,需要针对某些浏览器写补丁。目前先学习它是如何优化Vue2缺的点。在学习之前需要先引入Reflect这个概念。

    Reflect

    Reflect是为操作对象而设计的API,它是为了优化Object上面的一些工具函数,举个例子:
    Object.defineProperty(target,key,{
    get: {}
    set: {}
    })
    这个工具方法是设置某个对象某个属性的get和set属性,Reflect方法对应的写法是
    Reflect.get(target,key,property)
    Reflect.set(target,key,property)
    总结一下,Reflect就是为了净化Object,因为Object越来越笨重。

    Vue3实现响应式

    1.简单的代理,不加任何操作


    image.png
    image.png

    打印可以看到,修改set没有成功,因为set方法已经被代理了,之前的不起作用了,那么如果想要set生效,需要用Reflect加上如下的代码:
    let result = Reflect.set(target,name,property)
    为什么要用Reflect呢?我也不知道,官方就是这么推荐的,Proxy和Reflect算是一对好兄弟吧,Proxy能代理的方法,Reflect也都有对应的操作方法,下面开始进入正题。
    2.响应式写法
    Object.defineProperty()这个方法添加的get和set属性有先后顺序,就是必须先给属性加了这两个方法,后续修改赋值的时候,才会触发set方法,所以就会有新增和删除无法响应的缺点。
    Proxy优化这个缺点的思路就是,直接代理了读和取,我详细描述一下:
    1.通过Object.defineProperty(person,name,{
    get: {}
    set: {}
    }) 监听name属性的set

    person.name = 'hahaha' 执行这段代码,person会先调用person内置的set方法,然后再执行上面的set方法,那么新增一个city属性呢,
    person.city = '深圳'
    很显然无法监听到,因为上面并没有针对city绑定set和get方法
    2.通过Proxy监听
    proxyPerson.name = 'hahaha' 执行这段代码,person会试图调用person内置的set方法,然而因为proxyPerson这个实例已经全权代理了person的get和set,所以内置的原始的get和set方法不生效了,反而是直接执行proxyPerson代理的set方法,所以必须要调用Reflect.set去修改属性,很搞笑吧,因为底层干的活proxyPerson全部接过来了,这样实现响应式是不是就解决了无法监听新增和删除属性了呢?实现监听对象新增删除的代码:

    image.png
    3.深度监听
    还需要加入深度监听的逻辑,等等,不是直接代理对象就完了吗?然而并不是,proxy代理的只是对象的第一层属性,深度层级的属性需要另外代理,代码如下:
    添加红色框内的代码
    image.png
    控制台查看发现city属性也变成了proxy实例 image.png

    相关文章

      网友评论

          本文标题:ES6 Proxy和Reflect

          本文链接:https://www.haomeiwen.com/subject/zeelsktx.html