ES6 Proxy和Reflect

2020-08-28  本文已影响0人  小路_7bb8

前言:

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
上一篇下一篇

猜你喜欢

热点阅读