vue3 のプロキシに Reflect を使用する必要があるのはなぜですか?

PHPz
リリース: 2023-06-01 18:55:06
転載
1416 人が閲覧しました

vue を使用したことがある方は、vue の応答実装が Proxy を使用し、Reflect とともに使用されることをご存知でしょう。Proxy および Reflect ドキュメントを見ると最も明白なことは、Reflect オブジェクトの静的メソッドが同じ名前であることです。 Proxy プロキシ メソッド、および Reflect で操作できます。オブジェクトの使用、プロキシはオブジェクトをプロキシできますが、Proxy プロキシ メソッドで時々 Reflect を使用する必要がある理由が分かりませんでした。

基本操作

Reflect オブジェクトの static メソッドは 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}
ログイン後にコピー

Question

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}
ログイン後にコピー

上記の状況では、Reflect を使用せずにプロキシを完了できます。インターセプトの処理に 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
ログイン後にコピー

上の値の出力値は false です。期待される結果は true である必要がありますが、プロキシで使用されている元のオブジェクトの値が取得される必要があるため、これは元のオブジェクトなので値は false です

これは間違った値を指していますが、取得された値はまだ正しいですこれは特別な理由ではありません

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
ログイン後にコピー

あります問題です。出力結果が予期したものと異なります。これは子を指しているはずですが、親を指しています。

Reflect

If Reflect.get( obj, prop)obj[prop] に置き換えると、変化がないことを意味します 意味も結果も同じです これはまだ役に立たない受信側パラメータがあります。

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 はプロキシ オブジェクトを参照していません。これは元のオブジェクトを参照しますが、実行コンテキスト (これを特定の方法で変更せずに、呼び出した人が誰を指すかは、これが期待されるものであると言われています)、ここでは child が呼び出されます。 valueしたがって、予期されるポインタは child である必要があります。ここで、receiver[prop] を直接使用することを考えるかもしれませんが、それは機能しません。これにより、実行が発生します。オーバーフロー、receiver[prop] child.value と同等、child.value はまだ実行されていません。receiver[prop] は再度実行すると、無限に実行され続けます

Reflect.get(target, key, レシーバ)#Reflect の receiver パラメータ.get(target, key, レシーバー) は、追加せずに this を指すように変更されました。 thistarget を指し、追加後は指すようになりますto receiver

は、プロキシ オブジェクト this で役立ちます。いつでも取得できるように、Reflect

を使用する必要があります。期待値

概要

vue3 のプロキシ オブジェクトはすべて期待値を取得します。値はインターセプト中に収集および更新されるため、必ず Reflect# を使用してください##Proxy

# のインターセプト関数内で期待値を常に取得するにはどうすればよいですか? エージェントであることはエージェントを持たないことと同じです

  get: function (...arg) {
    return Reflect.get(...arg);
  },
ログイン後にコピー

以上がvue3 のプロキシに Reflect を使用する必要があるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:yisu.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート