如何使用Proxy拦截Map和Set的操作 #106
zhangyu1818
announced in
zh-cn
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Proxy
在代理普通对象的时候,只需要使用set
和get
两个拦截函数就可以实现一些效果。思考一下,我们在调用
Map
或Set
对象的时候,只会用到get
拦截,如map.get('key')
、map.set('key','value)
、map.has('key')
,实际传入的参数都是在Map
对象的方法里接收的,想要达到拦截的目的,实际需要操作的是Map
对象的get()
、set()
这些方法。函数拦截
我们需要对
Map
或Set
对象的方法进行拦截,在Proxy
中的get
拦截时,我们可以获取到调用的函数名。根据输出可以看出,调用
map
的set
、get
方法都调用了我们自己的函数,下一步就需要在自己的函数里,去调用map
对应的函数来实现拦截的功能且不影响原有功能。如何在
interceptors
拦截器里获取当前调用的对象呢?Reflect.get
的第三个参数,即是在调用时的this
,所以我们在interceptors
中访问的this
指向receiver
的值为经过Proxy
后的map
对象。然而如果直接在调用
this.get
是不行的,this
指向Proxy
后的对象,再通过此对象访问又会进入我们自定义的拦截器,就死循环了,所以我们需要在自定义对象中,通过this
这个Proxy
后的对象来找到原始的对象。所以我们需要在创建
Proxy
对象时,把原始对象和Proxy
对象之间建立一个映射,这样就可以通过Proxy
对象找到原始对象了。改写一下代码:
通过代理对象到原始对象的映射,我们可以通过
this
来找到传入的原始对象,再调用原始对象上的方法达到正确的效果,get
和set
的代理就完成了。其他方法还有
Set
对象实现的方法也是同理。this问题
在什么操作都没有做的时候,直接返回
Reflect.get(target, key, receiver)
,会出现这样一个错误,因为Map
的方法都在原型链Map.prototype
上,而值存在原对象内部槽[[MapData]]
上,而在通过代理后的Proxy
对象上没有[[MapData]]
,所以报错了,要解决这个问题,还是得修改this
指向。这个问题是我的个人见解,可能不一定对,欢迎讨论。
本文参考:
Beta Was this translation helpful? Give feedback.
All reactions