proxy objectとは
Proxy オブジェクトは、元のオブジェクトの代わりに使用できるオブジェクトを作成することができますが、プロパティの取得、設定、定義などの基本的な Object 操作を再定義することができます。
Proxy オブジェクトは、ES6 から導入されたオブジェクトであり、Proxy オブジェクトを使うと、代理(proxy)となる別のオブジェクトを作成することができる。
代理のオブジェクトを経由して元のオブジェクトを操作できる仕組みが Proxy にはあるため、プロパティを操作する際に独自の処理を挟んで実行させることができる。
Proxy オブジェクトは別のオブジェクトをラップし、プロパティやその他の読み取り/書き込みなどの操作をインターセプトします。必要に応じてそれらを独自に処理したり、オブジェクトが透過的にそれらを処理できるようにします。
オブジェクトの基本的な操作(get, setなど)を拡張して、独自の操作を追加することができる。
proxyオブジェクトのプロパティを変更すると、元のオブジェクトのプロパティの値も変更される。
まず、普通にproxyオブジェクトを用意してみる
const targetObj = {
hoge: "hoge",
fuga: "fuga"
}
const handler = {}
const proxyObj = new Proxy(targetObj, handler)
console.log(proxyObj.hoge) // -> "hoge"
proxyObj.hoge = "piyopiyo"
console.log(proxyObj.hoge) // -> "piyopiyo"
console.log(targetObj.hoge) // -> "piyopiyo"
handlerに、適切なメソッドを定義して挙動を操作することができる。ここで定義するメソッドのことを「トラップ」と呼んでいる。
プロパティへのアクセスを提供するメソッドです。 (オペレーティングシステムにおけるトラップの概念と同じようなものです。)
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Meta_programming#トラップ_trap
また、操作対象となる元のオブジェクトを「ターゲット」と呼ぶ。
以下のようにgetトラップで "hello"を返すようにhandlerを修正して実行してみる
const targetObj = {
hoge: "hoge",
fuga: "fuga"
}
const handler = {
get: (targetObj, prop, receiver) => {
return "hello"
}
}
const proxyObj = new Proxy(targetObj, handler)
proxyObj.hoge = "piyopiyo"
console.log(proxyObj) // -> "hello"
console.log(proxyObj.hoge) // -> "hello"
console.log(proxyObj.huga) // -> "hello"
console.log(proxyObj.piyo) // -> "hello"
console.log(targetObj.hoge) // -> "piyopiyo"
どんな呼び出し方をしても "hello" としか取得できなくなった(piyoオブジェクトは定義されていないが、それでもhelloと表示される)
ユースケースとしては、デフォルト値を設定しておいたり、プライベートプロパティを作ったり
この辺りは使用する機会はありそう
ReadOnlyはTypeScriptで代用できそうな気もする