https://ja.javascript.info/instanceof
instanceof
演算子でオブジェクトが特定のクラスに属しているのかを確認することができます。また、継承も考慮されます。
このようなチェックが必要なケースは多々あるかもしれません。ここでは、その型に応じて引数を別々に扱う 多形(ポリモーフィック) 関数を構築するために使用します。
構文は次の通りです:
それは obj
が Class
(または、それを継承しているクラス)に属している場合に true
を返します。
例:
コンストラクタ関数でも動作します。:
…また Array
のような組み込みクラスでも動作します。:
arr
は Object
クラスにも属していることに留意してください。Array
はプロトタイプ的に Object
を継承しているためです。
通常、instanceof
演算子はチェックのためにプロトタイプチェーンを検査します。この動きに対して、静的メソッド Symbol.hasInstance
でカスタムロジックが設定できます。
obj instanceof Class
のアルゴリズムはおおまかに次のように動作します。:
もし静的メソッド `Symbol.hasInstance` があれば、それ(`Class[Symbol.hasInstance](obj)`)を使います。これは `true` または `false` を返す必要があり、これで `instanceof` の振る舞いがカスタマイズできます。:
例:
ほとんどのクラスは `Symbol.hasInstance` を持っていません。このケースでは、通常のロジックが使用されます: `obj instanceOf Class` は `Class.prototype` が `obj` のプロトタイプチェーンうちの1つと等しいかをチェックします。
言い換えると、以下のような比較を行います:
```
obj.__proto__ == Class.prototype
obj.__proto__.__proto__ == Class.prototype
obj.__proto__.__proto__.__proto__ == Class.prototype
...
// いずれかが true の場合、 true が返却されます
// そうでない場合、チェーンの末尾に到達すると false を返します
```
上の例では、``rabbit.**proto** === Rabbit.prototype` なので、すぐに回答が得られます。
継承のケースでは、2つめのステップでマッチします:
これは、rabbit instanceof Animal
と Animal.prototype
を比較したものです。:
ところで、objA.isPrototypeOf(objB) というメソッドもあります。これは objA
が objB
のプロトタイプチェーンのどこかにあれば true
を返します。なので、obj instanceof Class
のテストは Class.prototype.isPrototypeOf(obj)
と言い換えることができます。
面白いことに、Class
コンストラクタ自身はチェックには参加しません! プロトタイプと Class.prototype
のチェーンだけです。
これは prototype
が変更されたときに興味深い結果につながります。
このように: