JavaScriptのProxyオブジェクトは、オブジェクトの基本的な操作(プロパティの取得、設定、削除など)をカスタマイズできる強力な機能です。この記事では、Proxyの基本的な使い方から実践的な活用方法まで、詳しく解説します。
Proxyとは
Proxyは、オブジェクトに対する基本的な操作をトラップ(インターセプト)し、カスタム動作を追加できるJavaScriptのビルトインオブジェクトです。ES2015(ES6)で導入され、オブジェクトの振る舞いを制御する新しい方法を提供しています。
基本的な使い方
Proxyオブジェクトは、以下の構文で作成します:
const proxy = new Proxy(target, handler);- `target`: 監視対象のオブジェクト
- `handler`: トラップを定義するオブジェクト
主要なトラップ(ハンドラー)
get トラップ
プロパティの取得をカスタマイズします:
const target = { name: 'John' };
const handler = {
get: function(target, prop) {
return prop in target ? target[prop] : '存在しないプロパティです';
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.name); // "John"
console.log(proxy.age); // "存在しないプロパティです"set トラップ
プロパティの設定をカスタマイズします:
const handler = {
set: function(target, prop, value) {
if (prop === 'age') {
if (!Number.isInteger(value)) {
throw new TypeError('年齢は整数である必要があります');
}
if (value < 0) {
throw new RangeError('年齢は0以上である必要があります');
}
}
target[prop] = value;
return true;
}
};
const person = new Proxy({}, handler);
person.age = 25; // OK
// person.age = -1; // エラー
// person.age = 'young'; // エラー実践的な活用例
バリデーション
オブジェクトのプロパティに対する入力検証を実装できます:
const validator = {
set: function(obj, prop, value) {
if (prop === 'email') {
if (!value.includes('@')) {
throw new Error('無効なメールアドレスです');
}
}
obj[prop] = value;
return true;
}
};
const user = new Proxy({}, validator);
user.email = 'user@example.com'; // OK
// user.email = 'invalid-email'; // エラーログ記録
オブジェクトの操作を監視し、ログを記録できます:
const handler = {
get: function(target, prop) {
console.log(`プロパティ ${prop} が参照されました`);
return target[prop];
},
set: function(target, prop, value) {
console.log(`プロパティ ${prop} が ${value} に設定されました`);
target[prop] = value;
return true;
}
};
const monitored = new Proxy({}, handler);パフォーマンスについての注意点
Proxyの使用は便利ですが、直接のオブジェクト操作と比べてわずかなパフォーマンスオーバーヘッドが発生します。大規模なアプリケーションや頻繁な操作が必要な場合は、このことを考慮に入れる必要があります。
まとめ
Proxyは、オブジェクトの操作をカスタマイズする強力な機能を提供します。バリデーション、ログ記録、デフォルト値の設定など、様々な用途に活用できます。適切に使用することで、より堅牢で保守性の高いコードを書くことができます。
ただし、パフォーマンスへの影響を考慮し、必要な場合にのみ使用することをお勧めします。Proxyは、モダンなJavaScript開発において重要なツールの1つとなっています。