从 Vue3 源码学习 Proxy & Reflect
source link: https://segmentfault.com/a/1190000040990093
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
作者:CodeOz
译者:前端小智
来源:dev
有梦想,有干货,微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。
本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。
这两个功能都出现在ES6中,两者配合得非常好!
Proxy
proxy 是一个外来的对象,他没有属性! 它封装了一个对象的行为。它需要两个参数。
const toto = new Proxy(target, handler)
target: 是指将被代理/包裹的对象
handler: 是代理的配置,它将拦截对目标的操作(获取、设置等)
多亏了 proxy ,我们可以创建这样的 traps
:
const toto = { a: 55, b:66 } const handler = { get(target, prop, receiver) { if (!!target[prop]) { return target[prop] } return `This ${prop} prop don't exist on this object !` } } const totoProxy = new Proxy (toto, handler) totoProxy.a // 55 totoProxy.c // This c prop don't exist on this object !
每个内部对象的 "方法" 都有他自己的目标函数
下面是一个对象方法的列表,相当于进入了 Target:
object methodtargetobject[prop]getobject[prop] = 55setnew Object()constructObject.keysownKeys目标函数的参数可以根据不同的函数而改变。
例如,对于get
函数取(target, prop, receiver(proxy本身)),而对于 set
函数取(target, prop, value (to set), receiver)
我们可以创建私有属性。
const toto = { name: 'toto', age: 25, _secret: '***' } const handler = { get(target, prop) { if (prop.startsWith('_')) { throw new Error('Access denied') } return target[prop] }, set(target, prop, value) { if (prop.startsWith('_')) { throw new Error('Access denied') } target[prop] = value // set方法返回布尔值 // 以便让我们知道该值是否已被正确设置 ! return true }, ownKeys(target, prop) { return Object.keys(target).filter(key => !key.startsWith('_')) }, } const totoProxy = new Proxy (toto, handler) for (const key of Object.keys(proxy1)) { console.log(key) // 'name', 'age' }
Reflect
Reflect 是一个静态类,简化了 proxy 的创建。
每个内部对象方法都有他自己的 Reflect 方法
object methodReflectobject[prop]Reflect.getobject[prop] = 55Reflect.setobject[prop]Reflect.getObject.keysReflect.ownKeys❓ 为什么要使用它?因为它和Proxy一起工作非常好! 它接受与 proxy 的相同的参数!
const toto = { a: 55, b:66 } const handler = { get(target, prop, receiver) { // 等价 target[prop] const value = Reflect.get(target, prop, receiver) if (!!value) { return value } return `This ${prop} prop don't exist on this object !` }, set(target, prop, value, receiver) { // 等价 target[prop] = value // Reflect.set 返回 boolean return Reflect.set(target, prop, receiver) }, } const totoProxy = new Proxy (toto, handler)
所以你可以看到 Proxy 和 Reflect api是很有用的,但我们不会每天都使用它,为了制作陷阱或隐藏某些对象的属性,使用它可能会很好。
如果你使用的是Vue框架,尝试修改组件的 props
对象,它将触发Vue的警告日志,这个功能是使用 Proxy
:) !
代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。
原文:https://dev.to/codeoz/proxy-r...
有梦想,有干货,微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。
本文 GitHub https://github.com/qq44924588... 已收录,有一线大厂面试完整考点、资料以及我的系列文章。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK