Reflectは、プロパティの取得、設定、削除、存在確認といった任意のオブジェクトに対する操作を、一貫した方法で実現するオブジェクトである。

Reflectオブジェクトは静的インスタンスで、コンストラクタではない。MathオブジェクトやJSONオブジェクトのように、グローバルオブジェクトをそのまま使う。

使いどころ

Reflectオブジェクトは、主にProxyオブジェクトと組み合わせて使うことを前提に設計されている。そのためReflectオブジェクトが持つ静的関数には、Proxyオブジェクトのトラップと呼ばれるプロパティ群と同じ名前がつけられている。

Proxyオブジェクトは、ターゲットとなるオブジェクトの処理をインターセプトし、任意に再定義する機能を持つ。トラップは、この再定義する1つ1つの処理に対応するプロパティ(関数)である。

Reflectが元のオブジェクトの値を転送し、Proxyがあれこれする(あるいはその逆)ようなイメージで使われる。

使い方

Reflectオブジェクトは、Proxyオブジェクトと組み合わせて使うのが一般的である。

Reflectオブジェクトのほぼすべてのメソッドは、他の構文やメソッドで代替できる。また、微妙な違いこそあるものの、そのうちのいくつかはObjectオブジェクトの同名の静的メソッドに対応している。

なので、やはりProxyオブジェクトと組み合わせた使い方をするのが妥当である。

js
const p = new Proxy(
  {},
  {
    deleteProperty(targetObject, property) {
      // Custom functionality: log the deletion
      console.log("Deleting property:", property);

      // Execute the default introspection behavior
      return Reflect.deleteProperty(targetObject, property);
    },
  }
);

引用元:Reflect – JavaScript | MDN

上記のサンプルコードでは、オブジェクトのプロパティが削除された際にログを出力する。

この例では、別にdeleteキーワードを使っても良いが、一貫した方法でオブジェクトに対する操作を記述できるため、Reflectが推奨される。ほんとうにそれだけがReflectのメリットなのかどうかは知らない。

メソッド一覧

メソッド名 概要
apply(target, thisArgument, argumentsList) targetに渡されたメソッドを指定されたthisと引数のリストで実行する。
Reflect.construct(target, argumentsList) targetに渡されたコンストラクタ関数を、指定された引数で実行する。
Reflect.construct(target, argumentsList, newTarget) 同上。newTargetは、new.targetを指定したい際に使う。
Reflect.defineProperty(target, propertyKey, attributes) targetに渡されたオブジェクトに、指定された引数を元にして新しいプロパティを追加する。
Reflect.deleteProperty(target, propertyKey) targetに渡されたオブジェクトから指定されたプロパティを削除する。
Reflect.get(target, propertyKey) targetに渡されたオブジェクトから、指定されたキーの値を取得する。
Reflect.get(target, propertyKey, receiver) 同上。receiverは、getterが呼び出されたときにthisの値を指定したいときに使う。
Reflect.getOwnPropertyDescriptor(target, propertyKey) targetに渡されたオブジェクトに、指定されたディスクリプたがある場合はそれを返す。なければundefinedを返す。
Reflect.getPrototypeOf(target) targetに渡されたオブジェクトのプロトタイプを返す。
Reflect.has(target, propertyKey) targetに渡されたオブジェクトが、渡されたキーのプロパティを持つかどうかを真偽値で返す。
Reflect.isExtensible(target) targetに渡されたオブジェクトが、拡張可能かどうかを真偽値で返す。
Reflect.ownKeys(target) targetに渡されたオブジェクトのキーの配列を返す。
Reflect.preventExtensions(target) targetに渡されたオブジェクトを拡張不能にする。成功したら真、失敗したら偽を返す。
Reflect.set(target, propertyKey, value) targetに渡されたオブジェクトの、指定されたキーに値を設定する。
Reflect.set(target, propertyKey, value, receiver) 同上。setterが呼び出されたときにthisの値を指定したいときに使う。
Reflect.setPrototypeOf(target, prototype) targetに渡されたオブジェクトに新たなプロトタイプを設定する。成功したら真、失敗したら偽を返す。

参考資料