今回は【JavaScript】Reflectについての備忘録です。
1: Reflectとは?
・Reflectとは、「JSエンジン内部の汎用的な関数」に直接アクセスできるオブジェクトのこと。
2:「Reflect」をもう少し詳しく
⬇︎
◾︎JSエンジンでは内部でのみ使用される「内部メソッド」というものを保持している。
[[Get]]
[[Set]]
[[Delete]]
[[Construct]]
⭕️◾︎「Reflect」によってこの「内部メソッド」を間接的に呼び出すことができる。
get
set
deleteProperty
construct
3:Reflectを使用する目的は、主に2つ。
⬇︎
①「内部メソッドを、Reflectに格納していく」ことによって【Reflectを通して内部メソッドにアクセスするという目的。】
②「Proxyと合わせて使用する目的。」
主に以上の2点です。
4:実際に【Reflectを通して内部メソッドにアクセスしてみよう。】
実践1: 下記のようにnew演算子などを用いて表記していた所を、【関数表記(Reflect.constructやReflect.hasなど)できるというのがReflectの特徴】となります。
・「new演算子」と「Reflect.construct」は、【同様の機能を内部メソッドとして、読んでいることになります。】
・つまりnew演算子を記述しないで、【Reflect.constructというメソッドを使用して、インスタンス化が行える】ということ。
//⬇︎class Cを作成しておく。
class C {
constructor(a, b) {
this.a = a;
this.b = b;
}
}
//1:普通の「new演算子」のインスタンス化
const obj1 = new C(1, 2);
console.log(obj1); //コンソール結果は、C {a: 1, b: 2}
//1-1:「1のnew演算子」を【Reflect.constructで、関数表記にできるのがReflectの特徴です。】
const obj2 = Reflect.construct(C, [1, 2]);
console.log(obj2); //コンソール結果は、C {a: 1, b: 2}
//2:「in」もReflectを使うことによって関数表記で使用できる。
console.log('a' in obj1); //コンソール結果は、aは存在するのでtrue
//2-1:Reflect.has()で関数表記で表す。
console.log(Reflect.has(obj1, 'c')); //コンソール結果は、cは存在しないのでfalse
実践2: Object.definePropertyのような「静的メソッド」は、インスタンス化を行わずに使用できるメソッドです。(補足:もともと静的メソッドの意味は、classのインスタンス化を行わずに使用できるメソッド。という意味です。)
・Object.definPropertyに対し【Reflect.defineProperty】は、「オブジェクトに格納されているdefineProperty(静的メソッド)を、Reflectに移植するという意味があります。」
⭕️Object.definePropertyとして使ってきたが、Reflect.definePropertyとして同様の機能を使えます。
//⬇︎Reflectに静的メソッドを移植する。以降同様のメソッドが追加された場合にはReflectの方が今後追加されていく。
Reflect.defineProperty;
//⬇︎Reflect.definepropertyを使うと「エラー処理などが、便利になります。」
//「Object.defineProperty」の場合は少し面倒くさく「エラー処理などはtry, catch,を使います。」
//「Reflect.defineproperty」は便利で「エラー処理などをif文で記述できる。エラーとなった場合は自動でfalseが返却されます。」
if (Reflect.defineProperty) {
//trueならここに処理で記載。
} else {
//エラーならfalseを処理で記載。
}
実践3: 「Reflectでよく使用する【GetとSetの使い方】について。
・「bobオブジェクトとTomオブジェクト」のような2つのオブジェクトが作成された状態から始めていきたいと思います。
・「getキーワード」は何かというと、プロパティにアクセスすると、このget関数が呼ばれ、
【return this._hello();に続く戻り値】が出力結果となります。(コンソールには_helloメソッドの「hello Tom」が実行される。)
//Reflectで良く使用する「Getの使い方」。
const bob = {
name: 'Bob',
_hello: function () {
console.log(`helloooo ${this.name}`);
},
};
const tom = {
name: 'Tom',
_hello: function () {
console.log(`hello ${this.name}`);
},
get hello() {
return this._hello();
},
};
tom.hello; //⬅︎1: 一般的なドット記法で「tomのhelloメソッド」を実行した場合。
//コンソール結果は、hello Tom
Reflect.get(tom, 'hello', bob); //⬅︎2:「内部メソッド的に1:をReflect.getで実行することができる。(第一引数に対象オブジェクト、第二引数に使用するメソッド、第三引数(receiver)は束縛したいオブジェクトを設定)」
//コンソール結果は、helloooo Bob
5: 「Reflect」をしっかり使おう
目的を明確にし、少しずつコードを叩けば親しみが生まれていきますね。(私はコード練習は少しずつ区切って練習していく派です。)
以上、簡単にですがReflectの備忘録でした。