2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【JavaScript】Reflectの使い方

Posted at

#はじめに

Udemyの【JS】ガチで学びたい人のためのJavaScriptメカニズムの講座の振り返りです。

前回の記事


#目的

  • Reflectについての理解を深める

#本題
###1.Reflect

ReflectとはJSエンジンの内部の汎用的な関数を呼び出すメソッドが格納されているオブジェクト

内部メソッド Reflect
[[Get]] get
[[Set]] set
[[Delete]] deleteProperty
[[Construct]] construct

JSエンジンの内部のメソッドをReflectで呼び出せる

Reflectの使用目的

  • 内部メソッドを呼び出す関数の格納場所
  • Proxyと合わせて使用するため

####例1

前提

クラスを定義している

main.js
class C {
  constructor(a, b) {
    this.a = a;
    this.b = b;
  }
}

今までのやり方通り、new演算子を用いてインスタンス化を行う

main.js
class C {
  constructor(a, b) {
    this.a = a;
    this.b = b;
  }
}

// インスタンス化したものを変数に格納
const obj1 = new C(1,2)
// C {a: 1, b: 2}と出力される
console.log(obj1);

これをReflectを使用してインスタンス化

main.js
class C {
  constructor(a, b) {
    this.a = a;
    this.b = b;
  }
}

// new演算子は内部的にReflectのConstructと同様に内部メソッドとして呼んでいる
// 下記のようにメソッドを使用してインスタンス化できる
// 第一引数にコンストラクタ関数を、第二引数に配列として値を設定する
const obj2 = Reflect.construct(C, [1,2]);
// obj1と同様にC {a: 1, b: 2}と出力される
console.log(obj2);

演算子を用いていたものを関数表記にできるというのがReflectの特徴

####例2

in演算子もReflectを用いて関数表記にできる

main.js
class C {
  constructor(a, b) {
    this.a = a;
    this.b = b;
  }
}

const obj2 = Reflect.construct(C, [1,2]);
console.log(obj2);
// aという値がobj2に含まれているかどうか確認できる(true or falseで出力)
console.log("a" in obj2);
// 上記は Reflectのhasというメソッドと同様の内部メソッドを呼んでいる
// 第一引数にはオブジェクト、第二引数には判定する値(ここではfalse)を入れる
console.log(Reflect.has(obj2, "c"))

####例3

静的メソッド(インスタンス化しなくても使えるメソッド)もReflectで使える

main.js
// 従来の書き方
Object.defineProperty
// 下記のように書くことも可
Reflect.defineProperty

Objectではエラーを返すが、Reflectではfalseを返す

main.js
// try...catch構文でエラー出力
try{
  Object.defineProperty
} catch(e) {

}

// 上記のように書くのは面倒
if(Reflect.defineProperty){
  // trueであればここのブロック結果が出力
} else {
  // falseであればここのブロック結果が出力
}

####例4

前提

二つのオブジェクトを用意

main.js
const bob = {
  name: 'Bob',
  _hello: function () {
    console.log(`hello ${this.name}`);
  }
}

const tom = {
  name: 'Tom',
  _hello: function () {
    console.log(`hello ${this.name}`);
  },
  get hello() {
    return this._hello();
  },
}

getをReflectを用いて使う

main.js
const bob = {
  name: 'Bob',
  _hello: function () {
    console.log(`hello ${this.name}`);
  }
}

const tom = {
  name: 'Tom',
  _hello: function () {
    console.log(`hello ${this.name}`);
  },
  get hello() {
    return this._hello();
  },
}
// 一般的なオブジェクトの呼び方
// hello Tom と出力される
tom.hello;
// これは内部的にはReflectのgetを呼んでいるのと同じ意味になる
// 第一引数にはオブジェクト、第二引数には値を入れる
Reflect.get(tom, "hello")
// 第三引数にはreceiverを入れることも可能
// receiverに登録されたオブジェクトがgetメソッドの中で使用されるthisに束縛される = bind
// 下記のようにbobを渡すとhello Bobと出力される
Reflect.get(tom, "hello", bob)
// 第三引数を書かなければ第一引数と同じになる

今日はここまで!

#参考にさせて頂いた記事

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?