Maison >interface Web >Voir.js >Pourquoi Reflect doit-il être utilisé pour Proxy dans vue3 ?
Ceux qui ont utilisé Vue savent que l'implémentation de la réponse de Vue utilise Proxy et qu'elle est utilisée avec Reflect. La chose la plus frappante lorsque l'on regarde les documents Proxy et Reflect est que la méthode statique de l'objet Reflect porte le même nom que le proxy Proxy. La méthode Reflect peut être utilisée pour manipuler des objets. , le proxy peut proxy des objets, mais je n'ai pas trouvé pourquoi vous devez parfois utiliser Reflect dans la méthode proxy Proxy
Les méthodes statiques de l'objet Reflect ont les mêmes noms. comme les méthodes de proxy proxy, et il existe 13 types de get et set sont les suivants
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}
Si le proxy n'effectue pas d'autres opérations et renvoie directement
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}
Dans la situation ci-dessus, le proxy peut gérer l'interception sans en utilisant Reflect, ce qui est beaucoup plus simple que d'utiliser Reflect
Différents objets, objets avec 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
La valeur imprimée dans la valeur ci-dessus est fausse et le résultat attendu doit être vrai, mais l'objet d'origine utilisé dans le proxy doit être la valeur, donc cela pointe vers l'objet d'origine, donc la valeur est fausse
Bien que cela pointe vers le mauvais, mais la valeur est toujours correcte Ce n'est pas une certaine raison
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
Il y a un problème. Les résultats de sortie sont différents de ceux attendus. Cela devrait pointer vers l'enfant, mais cela pointe vers le parent
Reflect s'allume
Si Reflect.get(obj, prop)
est remplacé par obj[prop]
. Cela équivaut à aucun changement. La signification et le résultat sont les mêmes. N'y a-t-il pas un autre paramètre du récepteur qui est inutile ? correctement, et le résultat est bien sûr conforme aux attentes. receive
r ne fait pas référence à l'objet proxy, ni à l'objet d'origine, mais au contexte d'exécution (avec La phrase est comme ça, sans changer cela dans d'une manière spécifique, celui qui appelle pointe vers qui, c'est ce qui est attendu), ici enfant
appelle valeur
, donc le point attendu devrait être enfant
. Ici, vous pouvez penser à utiliser directement receiver[prop]
, mais cela ne fonctionnera pas. Cela entraînera un débordement d'exécution. receiver[prop]
est équivalent à . child.value
, child.value
n'a pas encore été exécuté, et receiver[prop]
est à nouveau exécuté, et il continuera à s'exécuter indéfinimentReflect.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
指向正确,结果也当然和期望一致,receive
r的不是指代理对象,也不是指原对象,而是执行上下文(有句话是这么说的,不用特定方式改变this的情况下,谁调用指向谁,这就是期望的),这里child
调用的value
所以期望的指向应该是child
, 这里你可能想到直接用receiver[prop]
不行了,这样会出现执行溢出,receiver[prop]
相当于child.value
,child.value
还没执行完,receiver[prop]
又执行了,就会无限在执行
Reflect.get(target, key, receiver)
中的receiver
参数修改了this
指向,不加this
指向target
, 加了后指向receiver
代理对象中有用到
this
时一定要用到Reflect
,这样才能得到一直符合期望的值
vue3中的代理对象到得的都是符合期望的值,在拦截中做了收集和更新,所以一定要在Proxy
的拦截函数中使用Reflect
receiver
dans Reflect.get(target, key, Receiver)
modifie le pointeur this
sans ajouter this
Pointez sur target
, puis sur receiver
🎜🎜🎜🎜Lorsque this
est utilisé dans l'objet proxy, assurez-vous d'utiliser Réfléchissez code>, de cette façon, nous pouvons obtenir les valeurs attendues à tout moment🎜🎜🎜Résumé🎜🎜Les objets proxy dans vue3 obtiennent les valeurs attendues. Ils sont collectés et mis à jour lors de l'interception, ils doivent donc l'être. dans <code>ProxyReflect
dans la fonction d'interception de /code> pour traiter🎜🎜Comment toujours obtenir la valeur attendue, le proxy est comme s'il n'y avait pas de proxy🎜get: function (...arg) { return Reflect.get(...arg); },
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!