Microsoft Edge の機能を調べてみた - Proxy 初級編
Proxy とか Proxies とか呼ばれているもので、メタプログラミング用に Reflect と共に追加された機能。
一応、Reflect も Edge でつかえます。
現状、Edge でこの機能をそのまま使うことができません。
アドレスバー about:flags 入力し、「開発者向け設定」ページの「試験的な JavaScript 機能を有効にする」チェックを入れて Edge を再起動してください。
Proxy とは?
JavaScript でオブジェクトの動作を定義することができます。
すべてを定義することができるわけではありませんが、結構優れたやつです。
Proxy の名の通り、オブジェクトの代理人となり機能を追加してくれます。
Proxy が操作できること
Proxy がオブジェクトの操作を奪って処理することをトラップというようです。
トラップをまとめた関数群をハンドラと呼んでいるようです。
以下操作できるトラップと用意されている関数
関数呼び出しに対するトラップ | handler.apply() |
new によるコンストラクタ呼び出し対するトラップ | handler.construct() |
Object.defineProperty()に対するトラップ | handler.defineProperty() |
delete 操作に対するトラップ | handler.deleteProperty() |
for...in 文に対するトラップ | handler.enumerate() |
プロパティ値を取得することに対するトラップ | handler.get() |
Object.getOwnPropertyDescriptor()に対するトラップ | handler.getOwnPropertyDescriptor() |
GetPrototypeOf 内部メソッドに対するトラップ | handler.getPrototypeOf() |
in 操作に対するトラップ | handler.has() |
Object.isExtensible()に対するトラップ | handler.isExtensible() |
Object.getOwnPropertyNames()に対するトラップ | handler.ownKeys() |
Object.preventExtensions()に対するトラップ | handler.preventExtensions() |
プロパティ値を設定することに対するトラップ | handler.set() |
Object.setPrototypeOf()に対するトラップ | handler.setPrototypeOf() |
以上のものから、今回はよく使われると思われる set() と get() の解説です。
書き方
var p = new Proxy(target, handler);
target は操作したいオブジェクトで、handler は target を操作する関数を定義します。
空の Proxy をつくってみる
オブジェクトの値の設定時に処理を加える
以下のサンプルでは数値を入れると2倍になります。
handler の set の引数は オブジェクト名、プロパティ、値となっておりそれを取得します。
サンプルでは value が数値か判別して、数値であれば 2 をかけ、そうでなければそのままの値を設定します。
文字列や関数が値として設定される可能性があるため、何か処理する場合は型の判別をするケースが多くなると思います。
set の使用例としては変数を代入する際にバリデーションをしたい時や特定の文字を入れたくないなど、
オブジェクトの値の取得時に処理を加える
set() とは逆で値を取得するときに処理します。
Proxy を取消できるようにする
Proxy.revocable() で設定します。
Proxy.revocable() は {proxy: proxy, revoke: revoke} の2つのオブジェクトを持ち、
proxy に作成した Proxy を持ち、 revoke は取り消すための関数です。
Proxy の型
typeof で作成した proxy を調べると Proxy ではなくターゲットに設定したオブジェクトの型が返ります。
その為今回の場合は以下で値を調べることができます。
for(i in p){ console.log(i) }
for(i in p){ console.log(p[i]) }
Object.preventExtensions(p) でオブジェクトの拡張を禁止などができます。
罠
Edge の Proxy ですが想定にない動作をさせるとまだまだ不可思議な動きをします。
うっかり Proxy名.revoke を実行すると最悪 Edge が落ちますし、
F12 開発ツールのコンソールでは 100% 落ちる模様
参照元