概要: このチュートリアルでは、ES6のJavaScript Proxyオブジェクトについて学習します。
JavaScript Proxyオブジェクトとは
JavaScript Proxyは、別のオブジェクト(ターゲット)をラップし、ターゲットオブジェクトの基本操作をインターセプトするオブジェクトです。
基本操作とは、プロパティのルックアップ、代入、列挙、関数呼び出しなどです。
プロキシオブジェクトの作成
新しいプロキシオブジェクトを作成するには、次の構文を使用します
let proxy = new Proxy(target, handler);
Code language: JavaScript (javascript)この構文では
target– ラップするオブジェクトです。handler–targetの動作を制御するメソッドを含むオブジェクトです。handlerオブジェクト内のメソッドはトラップと呼ばれます。
簡単なプロキシの例
まず、userというオブジェクトを定義します
const user = {
firstName: 'John',
lastName: 'Doe',
email: '[email protected]',
}
Code language: JavaScript (javascript)次に、handlerオブジェクトを定義します
const handler = {
get(target, property) {
console.log(`Property ${property} has been read.`);
return target[property];
}
}
Code language: JavaScript (javascript)3番目に、proxyオブジェクトを作成します
const proxyUser = new Proxy(user, handler);
Code language: JavaScript (javascript)proxyUserオブジェクトは、userオブジェクトを使用してデータを格納します。 proxyUserは、userオブジェクトのすべてのプロパティにアクセスできます。

4番目に、proxyUserオブジェクトを介してuserオブジェクトのfirstNameおよびlastNameプロパティにアクセスします
console.log(proxyUser.firstName);
console.log(proxyUser.lastName);
Code language: CSS (css)出力
Property firstName has been read.
John
Property lastName has been read.
Doe
proxyUserオブジェクトを介してuserオブジェクトのプロパティにアクセスすると、handlerオブジェクトのget()メソッドが呼び出されます。
5番目に、元のオブジェクトuserを変更すると、変更はproxyUserに反映されます
user.firstName = 'Jane';
console.log(proxyUser.firstName);
Code language: JavaScript (javascript)出力
Property firstName has been read.
Jane
同様に、proxyUserオブジェクトの変更は、元のオブジェクト(user)に反映されます
proxyUser.lastName = 'William';
console.log(user.lastName);
Code language: JavaScript (javascript)出力
William
プロキシのトラップ
get()トラップ
get()トラップは、プロキシオブジェクトを介してtargetオブジェクトのプロパティにアクセスされたときに起動されます。
前の例では、proxyUserオブジェクトによってuserオブジェクトのプロパティにアクセスされると、メッセージが出力されます。
一般的に、プロパティにアクセスされたときにget()トラップでカスタムロジックを開発できます。
たとえば、get()トラップを使用して、ターゲットオブジェクトの計算プロパティを定義できます。 計算プロパティとは、既存のプロパティの値に基づいて値が計算されるプロパティです。
userオブジェクトにはfullNameプロパティがありませんが、get()トラップを使用して、firstNameおよびlastNameプロパティに基づいてfullNameプロパティを作成できます
const user = {
firstName: 'John',
lastName: 'Doe'
}
const handler = {
get(target, property) {
return property === 'fullName' ?
`${target.firstName} ${target.lastName}` :
target[property];
}
};
const proxyUser = new Proxy(user, handler);
console.log(proxyUser.fullName);
Code language: JavaScript (javascript)出力
John Doe
set()トラップ
set()トラップは、targetオブジェクトのプロパティが設定されたときの動作を制御します。
ユーザーのageは18歳以上でなければならないとします。 この制約を適用するには、次のようにset()トラップを開発します
const user = {
firstName: 'John',
lastName: 'Doe',
age: 20
}
const handler = {
set(target, property, value) {
if (property === 'age') {
if (typeof value !== 'number') {
throw new Error('Age must be a number.');
}
if (value < 18) {
throw new Error('The user must be 18 or older.')
}
}
target[property] = value;
}
};
const proxyUser = new Proxy(user, handler);
Code language: JavaScript (javascript)まず、ユーザーのageを文字列に設定します
proxyUser.age = 'foo';
Code language: JavaScript (javascript)出力
Error: Age must be a number.
Code language: JavaScript (javascript)次に、ユーザーの年齢を16に設定します
proxyUser.age = '16';
Code language: JavaScript (javascript)出力
The user must be 18 or older.
3番目に、ユーザーの年齢を21に設定します
proxyUser.age = 21;
エラーは発生しませんでした。
apply()トラップ
handler.apply()メソッドは、関数呼び出しのトラップです。 構文は次のとおりです
let proxy = new Proxy(target, {
apply: function(target, thisArg, args) {
//...
}
});
Code language: JavaScript (javascript)次の例を参照してください
const user = {
firstName: 'John',
lastName: 'Doe'
}
const getFullName = function (user) {
return `${user.firstName} ${user.lastName}`;
}
const getFullNameProxy = new Proxy(getFullName, {
apply(target, thisArg, args) {
return target(...args).toUpperCase();
}
});
console.log(getFullNameProxy(user)); //
Code language: JavaScript (javascript)出力
JOHN DOE
その他のトラップ
以下は、その他のトラップです
construct–new演算子の使用をトラップしますgetPrototypeOf–[[GetPrototypeOf]]への内部呼び出しをトラップしますsetPrototypeOf–Object.setPrototypeOfへの呼び出しをトラップしますisExtensible–Object.isExtensibleへの呼び出しをトラップしますpreventExtensions–Object.preventExtensionsへの呼び出しをトラップしますgetOwnPropertyDescriptor–Object.getOwnPropertyDescriptorへの呼び出しをトラップします
このチュートリアルでは、別のオブジェクトをラップしてそのオブジェクトの基本的な動作を変更するために使用されるJavaScript Proxyオブジェクトについて学習しました。