JavaScript - プロキシ:ビギナーズガイド
こんにちは、将来のプログラマーさんたち!今日は、JavaScriptのプロキシの世界への興味深い旅に出発します。これまで聞いたことがない方も安心してください。基本から始めて、少しずつ理解を深めていきます。このチュートリアルの終わりまでに、プロキシを使う技術に精通するでしょう!
JavaScriptでのプロキシとは?
まず、シンプルな類似を考えてみましょう。あなたが有名人(夢を追い続けましょう、でしょう?)だと思ってください。あなたは非常に有名で、アポointmentsやファンレター、以及其他の日常的な活動を誰かに処理してもらう必要があります。その代わりに動くこの人は、現実世界ではプロキシと呼ばれます。
JavaScriptでは、プロキシも同じように動作します。他のオブジェクト(ターゲットオブジェクトと呼びましょう)をラップして、そのオブジェクトの基本操作をインターセプトし、再定義することができます。すごいですね?
以下に基本的な例を示します:
let target = {
name: "John Doe",
age: 30
};
let handler = {
get: function(target, property) {
console.log(`Getting the ${property} property`);
return target[property];
}
};
let proxy = new Proxy(target, handler);
console.log(proxy.name);
このコードを実行すると、以下のように表示されます:
Getting the name property
John Doe
これを分解すると:
-
target
オブジェクトにname
とage
プロパティがあります。 -
handler
オブジェクトにget
トラップを作成します(トラップについては後ほど詳しく説明します)。 -
proxy
をProxy
コンストラクタを使って作成し、target
とhandler
を渡します。 -
proxy.name
にアクセスしようとすると、get
トラップが発動し、メッセージをログインしてから実際の値を返します。
JavaScript プロキシハンドラ
さあ、少しずつ深掘りしてみましょう。プロキシハンドラについて詳しく見ていきましょう。ハンドラは、プロキシのトラップを定義するオブジェクトです。トラップは、プロパティの查找、割り当て、列挙、関数呼び出しなどを提供するメソッドです。
以下にいくつかの一般的なハンドラトラップの表を示します:
トラップ | 説明 |
---|---|
get | プロパティアクセスをインターセプト |
set | プロパティ割り当てをインターセプト |
has |
in 演算子をインターセプト |
deleteProperty |
delete 演算子をインターセプト |
apply | 関数呼び出しをインターセプト |
construct |
new 演算子をインターセプト |
複数のトラップを使ったより包括的な例を見てみましょう:
let target = {
name: "Alice",
age: 25
};
let handler = {
get: function(target, property) {
console.log(`Accessing the ${property} property`);
return target[property];
},
set: function(target, property, value) {
console.log(`Setting the ${property} property to ${value}`);
target[property] = value;
return true;
},
has: function(target, property) {
console.log(`Checking if ${property} exists`);
return property in target;
}
};
let proxy = new Proxy(target, handler);
console.log(proxy.name); // getトラップを発動
proxy.job = "Developer"; // setトラップを発動
console.log("age" in proxy); // hasトラップを発動
このコードを実行すると以下のように出力されます:
Accessing the name property
Alice
Setting the job property to Developer
Checking if age exists
true
素晴らしいですね!私たちのプロキシは今、プロパティアクセス、割り当て、in
演算子をインターセプトしています!
JavaScript プロキシの用途
プロキシはどんなときに使うのか、と思っているかもしれませんね。「これはクールだけど、実際にどこで使うんだ?」と。素晴らしい質問です!プロキシにはいくつかの実用的な用途があります:
- バリデーション:プロキシを使ってオブジェクトにデータを設定する前にバリデーションを行うことができます。
let user = {
name: "Bob",
age: 30
};
let validator = {
set: function(obj, prop, value) {
if (prop === "age") {
if (typeof value !== "number") {
throw new TypeError("Age must be a number");
}
if (value < 0 || value > 120) {
throw new RangeError("Age must be between 0 and 120");
}
}
obj[prop] = value;
return true;
}
};
let proxiedUser = new Proxy(user, validator);
proxiedUser.age = 25; // これは動作します
try {
proxiedUser.age = "thirty"; // これはTypeErrorをスローします
} catch (e) {
console.log(e.message);
}
try {
proxiedUser.age = 150; // これはRangeErrorをスローします
} catch (e) {
console.log(e.message);
}
- ログ記録:プロキシを使ってオブジェクトプロパティへのアクセスを記録することができます。
let target = {
name: "Charlie",
age: 35
};
let logger = {
get: function(target, property) {
console.log(`Property ${property} accessed at ${new Date()}`);
return target[property];
}
};
let proxiedTarget = new Proxy(target, logger);
console.log(proxiedTarget.name);
console.log(proxiedTarget.age);
- デフォルト値:プロキシを使って存在しないプロパティにデフォルト値を提供することができます。
let handler = {
get: function(target, property) {
return property in target ? target[property] : "Property not found";
}
};
let proxy = new Proxy({}, handler);
proxy.name = "David";
console.log(proxy.name); // Outputs: David
console.log(proxy.age); // Outputs: Property not found
JavaScript プロキシハンドラ一覧
JavaScriptプロキシの旅を終えるにあたり、利用可能なすべてのハンドラトラップの包括的なリストを見てみましょう:
ハンドラトラップ | 説明 |
---|---|
get | プロパティ値の取得をインターセプト |
set | プロパティ値の設定をインターセプト |
has |
in 演算子をインターセプト |
deleteProperty |
delete 演算子をインターセプト |
apply | 関数呼び出しをインターセプト |
construct |
new 演算子をインターセプト |
getPrototypeOf |
Object.getPrototypeOf をインターセプト |
setPrototypeOf |
Object.setPrototypeOf をインターセプト |
isExtensible |
Object.isExtensible をインターセプト |
preventExtensions |
Object.preventExtensions をインターセプト |
getOwnPropertyDescriptor |
Object.getOwnPropertyDescriptor をインターセプト |
defineProperty |
Object.defineProperty をインターセプト |
ownKeys |
Object.getOwnPropertyNames とObject.getOwnPropertySymbols をインターセプト |
そして、ここまででJavaScriptプロキシの基本、いくつかの実用的な用途、そしてすべての利用可能なハンドラトラップについて説明しました。プロキシは強力なツールですが、慎重に使用する必要があります。特定の用途には非常に適していますが、パフォーマンスのオーバーヘッドが発生する場合があります。
このチュートリアルがJavaScriptプロキシを理解するのに役立ったことを願っています。引き続き練習し、コードを書き続けてください。それでは、プロキシを使いこなすプロへ!ハッピーコーディング!
Credits: Image by storyset