「object.constructor」を使いこなせるようになる!JavaScriptオブジェクトの型判定・継承関係確認の便利テクニック


JavaScriptのobject.constructorは、オブジェクトが生成されたコンストラクタ関数を指すプロパティです。つまり、このプロパティにアクセスすることで、そのオブジェクトがどのようなコンストラクタ関数で作られたのかを知ることができます。

使い方

const person = new Person('田中', 30);
console.log(person.constructor); // Person { name: '田中', age: 30 }

上記の例では、Personコンストラクタを使って生成されたpersonオブジェクトのconstructorプロパティにアクセスしています。その結果、Personコンストラクタそのものが返されています。

注意点

  • オブジェクトリテラルで生成されたオブジェクトの場合、そのオブジェクトのプロトタイプのコンストラクタ関数が返されます。
  • プリミティブ型(例:numberstringboolean)にはconstructorプロパティは存在しません。
  • 継承関係の確認
  • インスタンスかどうかを判定
  • オブジェクトの型判定
  • Object.prototype.constructorは、すべてのオブジェクトのデフォルトのコンストラクタ関数であるObjectコンストラクタ関数を指します。
  • constructorプロパティは、オブジェクトのプロトタイプチェーンを辿って、最初にconstructorプロパティを持つオブジェクトまで遡って返します。


オブジェクトの型判定

function isPerson(obj) {
  return obj instanceof Person; // instanceof 演算子を使う方法
  return obj.constructor === Person; // constructor プロパティを使う方法
}

const person = new Person('田中', 30);
const str = 'Hello';

console.log(isPerson(person)); // true
console.log(isPerson(str)); // false

このコードでは、isPerson関数という関数を定義しています。この関数は、引数として渡されたオブジェクトがPersonインスタンスかどうかを判定します。判定には、instanceof演算子とconstructorプロパティの2つの方法があります。

インスタンスかどうかを判定

function isInstanceOf(obj, constructor) {
  while (obj) {
    if (obj.constructor === constructor) {
      return true;
    }
    obj = Object.getPrototypeOf(obj);
  }
  return false;
}

const person = new Person('田中', 30);
const obj = {};

console.log(isInstanceOf(person, Person)); // true
console.log(isInstanceOf(person, Object)); // true
console.log(isInstanceOf(obj, Person)); // false

このコードでは、isInstanceOf関数という関数を定義しています。この関数は、引数として渡されたオブジェクトが指定されたコンストラクタ関数のインスタンスかどうかを判定します。判定には、プロトタイプチェーンを辿っていく方法を用いています。

class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(this.name + 'が鳴きました');
  }
}

class Dog extends Animal {
  constructor(name) {
    super(name);
  }

  bark() {
    console.log(this.name + 'が吠えました');
  }
}

const dog = new Dog('ポチ');

console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true
console.log(dog.constructor === Dog); // true
console.log(dog.constructor === Animal); // false

このコードでは、AnimalクラスとDogクラスという2つのクラスを定義しています。DogクラスはAnimalクラスを継承しています。

コード例では、dogというDogクラスのインスタンスを作成しています。そして、dogインスタンスがDogクラスのインスタンスかどうか、Animalクラスのインスタンスかどうかを判定しています。判定には、instanceof演算子とconstructorプロパティの2つの方法を用いています。



代替方法

  1. instanceof 演算子

    最も一般的な代替方法は、instanceof演算子を使用する方法です。これは、オブジェクトが指定されたコンストラクタのインスタンスかどうかを判定するものです。

    const person = new Person('田中', 30);
    console.log(person instanceof Person); // true
    

    上記の例では、personオブジェクトがPersonコンストラクタのインスタンスかどうかを判定しています。

  2. クラスの静的メソッド

    クラスがサポートされている場合は、クラスの静的メソッドを使用して、インスタンスかどうかを判定することができます。

    class Person {
      static isInstanceOf(obj) {
        return obj instanceof Person;
      }
    }
    
    const person = new Person('田中', 30);
    console.log(Person.isInstanceOf(person)); // true
    

    上記の例では、PersonクラスにisInstanceOfという静的メソッドを定義しています。このメソッドは、引数として渡されたオブジェクトがPersonクラスのインスタンスかどうかを判定します。

  3. Object.getPrototypeOf()

    Object.getPrototypeOf()関数を使用して、オブジェクトのプロトタイプを取得し、そのプロトタイプのconstructorプロパティにアクセスすることで、コンストラクタ関数を取得することができます。

    const person = new Person('田中', 30);
    const constructor = Object.getPrototypeOf(person).constructor;
    console.log(constructor === Person); // true
    

    上記の例では、personオブジェクトのプロトタイプを取得し、そのプロトタイプのconstructorプロパティにアクセスして、Personコンストラクタ関数を取得しています。

方法利点欠点
instanceof 演算子シンプルでわかりやすいクラスがサポートされていない場合は使用できない
クラスの静的メソッドクラス固有のロジックをカプセル化できる定義する必要がある
Object.getPrototypeOf()汎用性が高いやや複雑