isPrototypeOfメソッドは、対象のオブジェクトが、他のオブジェクトのプロトタイプチェーンに含まれるかどうかを評価するプロパティです。(プロトタイプチェーンについてはこちらの記事で分かりやすく解説されています!)
対象のオブジェクトが、他のオブジェクトに継承されているかどうかを調べることができます。
{対象のオブジェクト}.prototype.isPrototypeOf({このオブジェクトのプロトタイプチェーンに"対象のオブジェクト"が含まれるかどうか});
以下では、コンストラクタ関数Mutantのインスタンスに対し、Human、Mutant、Alienが生成したインスタンスのプロトタイプチェーンに含まれるかどうかを出力しています。
function Human () {}
function Mutant () {}
function Alien () {}
Mutant.prototype = Object.create(Human.prototype);
const mutant = new Mutant();
console.log(Human.prototype.isPrototypeOf(mutant)); // true
console.log(Mutant.prototype.isPrototypeOf(mutant)); // true
console.log(Alien.prototype.isPrototypeOf(mutant)); // false
オブジェクトmutantのプロトタイプチェーンはMutant <- Humanとなります。
Humanは、mutantのプロトタイプチェーンに含まれる為、1つ目のログはtrueになります。
Mutantは、mutantのプロトタイプチェーンに含まれる為、2つ目のログはtrueになります。
Alienは、mutantのプロトタイプチェーンに含まれない為、3つ目のログはfalseになります。
instanceofとの違い
isPrototypeOfのようなprototype(継承関係)を評価するメソッドと似たもので、instanceof演算子があります。
{このオブジェクトのプロトタイプチェーンに"対象のオブジェクト"が含まれるかどうか} instanceof {対象のオブジェクト}
先ほどのコードのisPrototypeOfの箇所をinstanceofに置き換えても、出力結果は同じになります。
console.log(mutant instanceof Human); // true
console.log(mutant instanceof Mutant); // true
console.log(mutant instanceof Alien); // false
上記のようにisPrototypeOfとinstanceofは基本的に同じ挙動を取る為、これらは同じものと考えても問題はないと思います。
ただ、以下のように使用可能な条件が若干異なるようです。
const Human = {
prototype: {}
};
function Mutant () {}
Mutant.prototype = Object.create(Human.prototype);
const mutant = new Mutant();
1. instanceofの右辺は、コンストラクタ(関数)である必要があります。
その為、通常のオブジェクトを右辺に設定すると、タイプエラーが発生します。
console.log(mutant instanceof Human); // TypeError: Right-hand side of 'instanceof' is not callable
2. 対してisPrototypeOfはObject.prototypeのメソッドなので、評価対象のオブジェクトがprototypeを持ち、それがオブジェクトであれば実行可能です。
console.log(Human.prototype.isPrototypeOf(mutant)); // true
他にも異なる点などがあれば、是非コメントいただけると嬉しいです🙏
最後まで読んでいただきありがとうございました!