JavaScript の Proxy と Reflect は ES6 の 2 つの新しいオブジェクトで、オブジェクトがアクセスされ操作されるときにカスタム ロジックをインターセプトして実行するのに役立ちます。この記事では、Proxy と Reflect のキャッチャー (インターセプターとも呼ばれます) の使用方法について説明し、それらが何を行うかの例を示します。
プロキシオブジェクトのキャッチャー
JavaScript では、Proxy オブジェクトを使用して、他のオブジェクトのアクセスと操作を代理することができます。ターゲット オブジェクトの操作をインターセプトし、カスタム ロジックを実行するためのいくつかのキャッチャー (インターセプター) が提供されます。よく使用されるキャッチャーは次のとおりです。
キャッチャーを獲得する
get キャッチャーは、オブジェクト プロパティの読み取り操作をインターセプトし、読み取り前にカスタム ロジックを実行できます。get キャッチャーは、ターゲット オブジェクトとプロパティ名という 2 つのパラメーターを受け取ります。
Proxy.get キャッチャーを使用してオブジェクト プロパティの読み取りをインターセプトする例を次に示します。
const obj = {
name: 'Alice',
age: 18,
};
const proxy = new Proxy(obj, {
get(target, prop) {
console.log(`读取属性 ${
prop}`);
return Reflect.get(target, prop);
},
});
console.log(proxy.name); // 读取属性 name,输出 Alice
console.log(proxy.age); // 读取属性 age,输出 18
上の例では、Proxy.get メソッドを使用して、オブジェクト プロパティの読み取り操作をインターセプトします。元のオブジェクトとは異なり、プロパティを読み取る前に情報を出力します。インターセプターでは、検証や計算などの任意のカスタム ロジックを実行できます。
セットキャッチャー
セット キャッチャーは、オブジェクト プロパティの設定操作をインターセプトし、設定前にカスタム ロジックを実行できます。set catcher は、ターゲット オブジェクト、プロパティ名、プロパティ値の 3 つのパラメータを受け取ります。
Proxy.set キャッチャーを使用してオブジェクトのプロパティ設定をインターセプトする例を次に示します。
const obj = {
name: 'Alice',
age: 18,
};
const proxy = new Proxy(obj, {
set(target, prop, value) {
console.log(`设置属性 ${
prop} 的值为 ${
value}`);
return Reflect.set(target, prop, value);
},
});
proxy.name = 'Bob'; // 设置属性 name 的值为 Bob
proxy.age = 20; // 设置属性 age 的值为 20
上記の例では、Proxy.set メソッドを使用して、オブジェクト プロパティの設定操作をインターセプトします。プリミティブ オブジェクトとは異なり、プロパティを設定する前に情報を出力します。インターセプターでは、検証や計算などの任意のカスタム ロジックを実行できます。
キャッチャーあり
has キャッチャーは、in 演算子の操作をインターセプトし、操作の前にカスタム ロジックを実行できます。has キャッチャーは、ターゲット オブジェクトとプロパティ名という 2 つのパラメーターを受け取ります。
Proxy.has キャッチャーを使用して in 演算子の操作をインターセプトする例を次に示します。
const obj = {
name: 'Alice',
age: 18,
};
const proxy = new Proxy(obj, {
has(target, prop) {
console.log(`检查属性 ${
prop} 是否存在`);
return Reflect.has(target, prop);
},
});
console.log('name' in proxy); // 检查属性 name 是否存在,输出 true
console.log('gender' in proxy); // 检查属性 gender 是否存在,输出 false
上の例では、Proxy.has メソッドを使用して in 演算子の操作をインターセプトします。元のオブジェクトとは異なり、プロパティを確認する前に情報を出力します。インターセプターでは、検証や計算などの任意のカスタム ロジックを実行できます。
キャッチャーを適用する
適用キャッチャーは、関数の呼び出し操作をインターセプトし、呼び出す前にカスタム ロジックを実行できます。適用キャッチャーは、ターゲット関数、ターゲット オブジェクト、関数パラメーター配列の 3 つのパラメーターを受け取ります。
Proxy.apply トラップを使用して関数呼び出しをインターセプトする例を次に示します。
function sum(a, b) {
return a + b;
}
const proxy = new Proxy(sum, {
apply(target, thisArg, args) {
console.log(`调用函数 ${
target.name}(${
args})`);
return Reflect.apply(target, thisArg, args);
},
});
console.log(proxy(1, 2)); // 调用函数 sum(1,2),输出 3
上の例では、Proxy.apply メソッドを使用して関数呼び出し操作をインターセプトします。元の関数とは異なり、関数を呼び出す前に情報を出力します。インターセプターでは、検証や計算などの任意のカスタム ロジックを実行できます。
Reflect オブジェクトのキャプチャ
Reflect オブジェクトは ES6 の新しいオブジェクトで、オブジェクト操作を実行するための静的メソッドのセットを提供します。これらのメソッドは Proxy のキャッチャーと 1 対 1 に対応しており、キャッチャーと同じ操作を実行するために使用できます。一般的に使用される Reflect メソッドをいくつか示します。
Reflect.getメソッド
Reflect.get メソッドはオブジェクト プロパティの値を読み取るために使用され、その構文は次のとおりです。
Reflect.get(target, propertyKey[, receiver])
このうち、target はターゲット オブジェクトを表し、propertyKey はプロパティ名を表し、receiver はプロパティが配置されているオブジェクトを表します (オプション)。
以下は、Reflect.get メソッドを使用してオブジェクトのプロパティを読み取る例です。
const obj = {
name: 'Alice',
age: 18,
};
console.log(Reflect.get(obj, 'name')); // 输出 Alice
console.log(Reflect.get(obj, 'age')); // 输出 18
上の例では、Reflect.get メソッドを使用してオブジェクト プロパティの値を読み取ります。ドットや角かっこを使用してプロパティにアクセスする場合とは異なり、Reflect.get メソッドは名前を知らなくてもプロパティの値を読み取ることができます。
Reflect.set メソッド
Reflect.set メソッドはオブジェクト プロパティの値を設定するために使用され、その構文は次のとおりです。
Reflect.set(target, propertyKey, value[, receiver])
このうち、target はターゲット オブジェクトを表し、propertyKey は以下を表します。
const obj = {
name: 'Alice',
age: 18,
};
const proxy = new Proxy(obj, {
set(target, prop, value, receiver) {
console.log(`设置属性 ${
prop} 的值为 ${
value}`);
return Reflect.set(target, prop, value, receiver);
},
});
proxy.age = 20; // 设置属性 age 的值为 20,输出 "设置属性 age 的值为 20"
console.log(proxy.age); // 输出 20
上記の例では、Proxy.set メソッドを使用して、プロパティ値の設定操作をインターセプトします。プリミティブ オブジェクトとは異なり、プロパティを設定する前に情報を出力します。インターセプターでは、検証や計算などの任意のカスタム ロジックを実行できます。
Reflect.has メソッド
Reflect.has メソッドは、オブジェクトに指定されたプロパティが含まれているかどうかを確認するために使用されます。その構文は次のとおりです。
Reflect.has(target, propertyKey)
このうち、target は対象オブジェクトを表し、propertyKey はプロパティ名を表します。
以下は、Reflect.has メソッドを使用してオブジェクトのプロパティをチェックする例です。
const obj = {
name: 'Alice',
age: 18,
};
console.log(Reflect.has(obj, 'name')); // 输出 true
console.log(Reflect.has(obj, 'gender')); // 输出 false
上記の例では、Reflect.has メソッドを使用して、オブジェクトに指定されたプロパティが含まれているかどうかを確認します。in 演算子や hasOwnProperty メソッドの使用とは異なり、Reflect.has メソッドは数値や文字列などのブール値以外の値を返すことができます。
Reflect.apply 方法
Reflect.apply メソッドは関数の呼び出しに使用され、その構文は次のとおりです。
Reflect.apply(target, thisArg, args)
このうち、target は対象関数、thisArg は関数の this 値、args は関数のパラメータ配列を表します。
以下は、Reflect.apply メソッドを使用して関数を呼び出す例です。
function sum(a, b) {
return a + b;
}
console.log(Reflect.apply(sum, null, [1, 2])); // 输出 3
上の例では、Reflect.apply メソッドを使用して関数を呼び出しました。関数を直接呼び出す場合とは異なり、Reflect.apply メソッドでは関数の this 値を指定し、パラメーター配列を関数のパラメーターとして使用できます。