vue3中的Proxy一定要用Reflect的原因解析 - 网站

vue3中的Proxy一定要用Reflect的原因解析

分类:Vue.js 教程 · 发布时间:2023-10-11 04:05 · 阅读:9717

Reflect可以操作对象使用, proxy可以代理对象,但没有找到为啥有时一定要在Proxy代理方法中使用Reflect,这篇文章主要介绍了vue3中的Proxy一定要用Reflect的原因解析,需要的朋友可以参考下

用过vue的知道,vue的响应实现用的Proxy,且里面是配合Reflect用的,查看Proxy和Reflect文档最显眼的是Reflect对象的静态方法和Proxy代理方法的命名相同,Reflect可以操作对象使用, proxy可以代理对象,但没有找到为啥有时一定要在Proxy代理方法中使用Reflect

基本操作

Reflect对象的静态方法和Proxy代理方法的命名相同,都有13种,示例get,set如下

const tempObj = { a: 1 }; Reflect.get(tempObj, 'a'); // 返回 1 Reflect.set(tempObj, 'a', 2); // 返回true 表示设置成功, a的值变2 const tempObj1 = { a: 1 }; const handler = { get: function (obj, prop, receiver) { return prop === 'a' ? 1000 : obj[prop]; }, set: function (obj, prop, value, receiver) { console.log(prop); obj[prop] = prop === 'a' ? 6 : value; return true; }, }; const proxyObj = new Proxy(tempObj1, handler); proxyObj.a; // proxyObj => {a: 1000} proxyObj.a = 2; // proxyObj => {a: 6}

疑问

如果Proxy不做其它操作直接正常返回

const tempObj1 = { a: 1 }; const handler = { get: function (obj, prop, receiver) { return obj[prop]; }, set: function (obj, prop, value, receiver) { obj[prop] = value return true; }, }; const proxyObj = new Proxy(tempObj1, handler); proxyObj.a; // proxyObj => {a: 1} proxyObj.a = 2; // proxyObj => {a: 2}

以上面情况完Proxy可以不使用Reflect处理拦截,比使用Reflect简单多了

不一样的对象, 带有get的对象

const tempObj1 = { a: 1, get value() { console.log(this === proxyObj); // false return this.a; }, }; const handler = { get: function (obj, prop, receiver) { return obj[prop]; }, set: function (obj, prop, value, receiver) { obj[prop] = value; return true; }, }; const proxyObj = new Proxy(tempObj1, handler); proxyObj.value; // 1

上面value中的打印的值为false,期望的结果应该true, 但应该代理中用的原对象取值所以this指向了原对象,所以值为false

虽然this指错了,但得到值还是正确定,这不是一定的理由

const parent = { a: 1, get value() { console.log(this === child); // false return this.a; }, }; const handler = { get: function (obj, prop, receiver) { return obj[prop]; }, set: function (obj, prop, value, receiver) { obj[prop] = value; return true; }, }; const proxyObj = new Proxy(parent, handler); const child = Object.setPrototypeOf({ a: 2 }, proxyObj); child.value; // 1

这就有问题了,输出的结果都和期望的不一样了,this应该指向child,但指向了parent

Reflect上场

要是Reflect.get(obj, prop)换成obj[prop],这等于没换,意义和结果是一样的,这不是还有一个receiver参数没有用嘛

const parent = { a: 1, get value() { console.log(this === child); // true return this.a; }, }; const handler = { get: function (obj, prop, receiver) { Reflect.get(obj, prop) - return obj[prop]; + retrun Reflect.get(obj, prop, receiver) }, set: function (obj, prop, value, receiver) { - obj[prop] = value; + Reflect.get(obj, prop, value, receiver) return true; }, }; const proxyObj = new Proxy(parent, handler); const child = Object.setPrototypeOf({ a: 2 }, proxyObj); child.value; // 2

this指向正确,结果也当然和期望一致,receiver的不是指代理对象,也不是指原对象,而是执行上下文(有句话是这么说的,不用特定方式改变this的情况下,谁调用指向谁,这就是期望的),这里child调用的value所以期望的指向应该是child, 这里你可能想到直接用receiver[prop]不行了,这样会出现执行溢出,receiver[prop]相当于child.valuechild.value还没执行完,receiver[prop]又执行了,就会无限在执行

Reflect.get(target, key, receiver)中的receiver参数修改了this指向,不加this指向target, 加了后指向receiver

代理对象中有用到this时一定要用到Reflect,这样才能得到一直符合期望的值

总结

vue3中的代理对象到得的都是符合期望的值,在拦截中做了收集和更新,所以一定要在Proxy的拦截函数中使用Reflect处理

怎么一直拿到符合期望的值,代理了像没有代理一样

  get: function (...arg) { return Reflect.get(...arg); },

到此这篇关于为啥vue3中的Proxy一定要用Reflect的文章就介绍到这了,更多相关vue3中Proxy使用Reflect内容请搜索0133技术站以前的文章或继续浏览下面的相关文章希望大家以后多多支持0133技术站!

标签:
vue3 Proxy Reflect

相关文章

vue加载视频流,实现直播功能的过程

这篇文章主要介绍了vue加载视频流,实现直播功能的过程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

Vue2项目升级到Vue3的详细教程

看到好多开源项目都升级了vue3,下面这篇文章主要给大家介绍了关于Vue2项目升级到Vue3的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

解决v-model双向绑定失效的问题

这篇文章主要介绍了解决v-model双向绑定失效的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

Vue面试必备之防抖和节流的使用

在这篇文章中,大家会了解到如何在 Vue 组件中使用防抖和节流控制 观察者(watchers)以及事件处理程序,文中的示例代码简洁易懂,希望对大家有所帮助

element中async-validator异步请求验证使用

本文主要介绍了element中async-validator异步请求验证使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

返回分类 返回首页