概要: このチュートリアルでは、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オブジェクトについて学習しました。