概要
javascriptでオブジェクトのクラスを、instanceof演算子で調べる方法を試してみます。
具体的には、次のように書きます。
オブジェクトA instanceof クラスB
上記はオブジェクトAがクラスBのプロトタイプチェーンにコンストラクタのprototypeが存在するかを調べてます。
サンプル
次のコードを書いて動かしてみます。
//テスト用クラス function Testclass() { } //オブジェクトを生成 var testobj = new Testclass(); //instanceof演算子で判定 console.log(testobj instanceof Testclass);
出力結果はtrueになります。
考察
instanceof演算子は、オブジェクト自身のプロトタイプチェーンにコンストラクタのprototypeが含まれているかを判定するので、
「オブジェクトが何を継承しているか」
という判定方法になります。
ということは、生成したオブジェクトに別のオブジェクトのプロトタイプを入れると、みかけ上は同じオブジェクトだとしても、結果は変わってしまいます。
試しに、次のようなコードを書いてみます。
//テスト用クラス function Testclass() { } //オブジェクトを生成 var testobj = new Testclass(); //instanceof演算子で判定 console.log(testobj instanceof Testclass); //生成したオブジェクトにStringオブジェクトのプロトタイプを入れる testobj.__proto__ = String.prototype; //instanceof演算子で判定 console.log(testobj instanceof Testclass);
先ほど書いたサンプルに、Stringオブジェクトを入れる処理をして、
同様にinstanceof演算子で判定しています。
出力結果はfalseになります。
生成したオブジェクトに対し、オブジェクトのプロトタイプチェーンに含まれるかを判定する
では、生成したオブジェクトに対し、オブジェクトのプロトタイプチェーンに含まれるかを判定するには、
instanceof演算子ではなくisPrototypeOf()メソッドを使って調べます。
構文は次のようになります。
オブジェクトA.isPrototypeOf(検索対象のオブジェクト)
試しに、次のようにサンプルコードを書いてみます。
function Testclass2() {} function Testclass3() {} Testclass3.prototype = Object.create(Testclass2.prototype); let testobj2 = new Testclass3(); console.log(Testclass3.prototype.isPrototypeOf(testobj2));
上記の出力結果はtrueになります。
生成したオブジェクトtestobj2は、元々Testclass3のプロトタイプチェーンに、Testclass2のプロトタイプを代入している為、少しわかりづらいですが、、
Testclass3のプロトタイプオブジェクトに対して、testobj2をisPrototypeOfで判定するとtrueと判定されます。
では、少し雑ですが、上記のコードを次のように書き換えてみます。
function Testclass4() {} function Testclass5() {} Testclass5.prototype = Object.create(Testclass4.prototype); let testobj4 = new Testclass4(); console.log(Testclass5.prototype.isPrototypeOf(testobj4));
出力結果はfalseになります。
ほとんどコードは同じに見えますが、違いは「let testobj4 = new Testclass4();」の箇所で、
testobj4のオブジェクトを生成する際、Testclass5から生成するのではなく、Testclass4から生成しています。
そうすると、「Testclass5.prototype.isPrototypeOf(testobj4)」の判定は、testobj4のオブジェクトには「Testclass5」のプロトタイプチェーンが含まれていない為、判定はfalseになります。