Proxyオブジェクトが結構便利だったので書いてみます。
Proxy
Proxy オブジェクトは、基本的な操作 (例えばプロパティの検索、代入、列挙、関数の起動など) について独自の動作を定義するために使用します。
const proxy = new Proxy(targetObject, handler)
targetObject
に対象のオブジェクト、handler
にはそのオブジェクトに対してどうするのか、トラップと呼ばれるメソッドを定義して渡します。
よく使うであろうget
とset
だけ紹介しときます。
get
const user = { name: 'Alice', age: 30 } const proxy = new Proxy(user, { get(target, name) { if (target[name] <= 30) return 17 return target[name] } }) console.log(proxy.age) // 17
get
はconsole.log
など、そのプロパティにアクセスがあったとき、どうやって返すのかを定義できます。
例の場合はage
が30以上なら17
と表示されます。永遠のなんとやら・・・。
set
次にset。
const user = { name: 'Alice', age: null } const proxy = new Proxy(user, { set(target, name, value) { if (name === 'age') { target[name] = 17 return true } return Reflect.set(...arguments) } }) proxy.age = 30 console.log(proxy.age) // 17
例は何をいれても17になります(永遠の...)
使い所
表なりなんなり、データを一覧で表示しないといけないときとか。
条件として、nullとか空文字は-
で表示してー!みたいな場合。
普通に書くと。。。
const rows = dataList.map(data => { return ` <tr> <td>${data.A !== null ? data.A : '-'}</td> <td>${data.B !== null ? data.B : '-'}</td> <td>${data.C !== null ? data.C : '-'}</td> <td>${data.D !== null ? data.D : '-'}</td> </tr> ` }) // tbodyなりにrowsをappend
何も意識せず書くとこんな感じでテーブルのデータ組むと思います。
まとめるならこんな感じ。
const formatter = value => value !== null ? value : '-' const rows = dataList.map(data => { return ` <tr> <td>${formatter(data.A)}</td> <td>${formatter(data.B)}</td> <td>${formatter(data.C)}</td> <td>${formatter(data.D)}</td> </tr> ` })
やってることが単純なので、このレベルならこれで十分ですね正直。。。
Proxyを使うと、
const rows = dataList.map(data => { const p = new Proxy(data, { get(target, name) { if (target[name] === null) return '-' return target[name] } }) return ` <tr> <td>${p.A}</td> <td>${p.B}</td> <td>${p.C}</td> <td>${p.D}</td> </tr> ` })
HTML作ってる部分はスッキリしますね。
その他
ループでnewしまくるのが良いかどうのかってのはちょっとありそうですが、便利な機能なのでもう少し突き詰めたいところ 。
set
なんかはオブジェクトの変更監視もできる気がするので、いわゆるオレオレstore的なのが作れるかも?
Vue3.0でProxyが使われてるとかそんな話を聞いたことがあるようなないような。
そもそもProxyってこんな使い方して良いのかなという疑問は残るんですが。
どうなんでしょう?