このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docsコミュニティーについてもっと知り、仲間になるにはこちらから。
instanceof
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2015年7月.
instanceof 演算子は、あるコンストラクターのprototype プロパティが、あるオブジェクトのプロトタイプチェーンの中のどこかに現れるかどうかを検査します。返値は論理値です。この動作はSymbol.hasInstance でカスタマイズすることができます。
In this article
試してみましょう
function Car(make, model, year) { this.make = make; this.model = model; this.year = year;}const auto = new Car("Honda", "Accord", 1998);console.log(auto instanceof Car);// 予想される結果: trueconsole.log(auto instanceof Object);// 予想される結果: true構文
object instanceof constructor引数
object検査するオブジェクトです。
constructor検査対象の関数です。
例外
TypeErrorconstructorがオブジェクトでない場合、発生します。constructorが[Symbol.hasInstance]()メソッドを持っていない場合は、関数でなければなりません。
解説
instanceof 演算子は、object のプロトタイプチェーンにconstructor.prototype が存在することを検査します。これ通常(ただし常にではない)、objectがconstructorで構築されたということを意味しています。
// コンストラクターを定義function C() {}function D() {}const o = new C();// true : Object.getPrototypeOf(o) === C.prototype であるためo instanceof C;// false : D.prototype は o のプロトタイプチェーンのどこにも存在しないためo instanceof D;o instanceof Object; // true : なぜなら...C.prototype instanceof Object; // true であるため// `constructor.prototype` を再代入。// このようなことは、めったにすべきではありません。C.prototype = {};const o2 = new C();o2 instanceof C; // true// false : C.prototype は o のプロトタイプチェーンの// どこにも存在しないためo instanceof C;D.prototype = new C(); // C を D の [[Prototype]] リンクに追加const o3 = new D();o3 instanceof D; // trueo3 instanceof C; // true : o3 のプロトタイプチェーンに C.prototype があるためなお、オブジェクト作成後にconstructor.prototype が再代入されると(通常は推奨されません)、instanceof 検査の値が変化する可能性があります。また、Object.setPrototypeOf を使用してobject のプロトタイプを変更することで、この値を変更することもできます。
クラスも同様に動作する方法です。クラスにもprototype プロパティが存在するためです。
class A {}class B extends A {}const o1 = new A();// true : Object.getPrototypeOf(o1) === A.prototype であるためo1 instanceof A;// false : B.prototype が o1 のプロトタイプチェーン内になったためo1 instanceof B;const o2 = new B();// true : Object.getPrototypeOf(Object.getPrototypeOf(o2)) === A.prototype であるためo2 instanceof A;// true : Object.getPrototypeOf(o2) === B.prototype であるためo2 instanceof B;バインド済み関数については、instanceof は対象とする関数のprototype プロパティを見ていきます。これは、バインド済み関数にはprototype が存在しないためです。
class Base {}const BoundBase = Base.bind(null, 1, 2);console.log(new Base() instanceof BoundBase); // trueinstanceof と Symbol.hasInstance
constructor がSymbol.hasInstance メソッドを持つ場合、そのメソッドが優先的に呼び出され、引数としてobject のみを受け取り、this としてconstructor が渡されます。
// このクラスは、具体的なフラグをプロパティとして持つ限り、プレーンオブジェクトが// このクラスのインスタンスであるように偽装できるようにするclass Forgeable { static isInstanceFlag = Symbol("isInstanceFlag"); static [Symbol.hasInstance](obj) { return Forgeable.isInstanceFlag in obj; }}const obj = { [Forgeable.isInstanceFlag]: true };console.log(obj instanceof Forgeable); // trueすべての関数は既定でFunction.prototype を継承するため、右辺が関数である場合、ほとんどの場合はFunction.prototype[Symbol.hasInstance]() メソッドがinstanceof の動作を指定します。instanceof の正確なアルゴリズムについては、Symbol.hasInstance ページを参照してください。
instanceof と複数の領域
JavaScriptの実行環境(ウィンドウ、フレームなど)は、それぞれの独自の領域に属しています。つまり、組み込まれているものも変わります(別々なグローバルオブジェクト、別々なコンストラクター、など)。これにより予期せぬ結果になる場合があります。例えば、[] instanceof window.frames[0].Array はfalse を返します。Array.prototype !== window.frames[0].Array.prototype であり、配列は前者を継承しているからです。
これは、始めはわかりにくいかもしれませんが、スクリプトで複数のフレームやウィンドウを扱い、オブジェクトをあるコンテキストから別のコンテキストへ関数を経由して渡すようになると、正当かつ重要な事項になります。例えば、Array.isArray() を使用すると、与えられたオブジェクトが実際に配列であるかどうかを安全にチェックできます。
例えば、別のコンテキストであるNode がSVGElement であるかどうかをチェックするには、myNode instanceof myNode.ownerDocument.defaultView.SVGElement を使用してください。
例
>instanceof を String に使用
次の例では、instanceof をString オブジェクトに使用した場合の動作を示しています。
const literalString = "これは文字列リテラルです";const stringObject = new String("コンストラクターで作成された String です");literalString instanceof String; // false : 文字列リテラルは String ではないstringObject instanceof String; // trueliteralString instanceof Object; // false : 文字列リテラルは Object ではないstringObject instanceof Object; // truestringObject instanceof Date; // falseinstanceof を Map に対して使用
次の例では、instanceof をMap オブジェクトに使用した場合の動作を示しています。
const myMap = new Map();myMap instanceof Map; // truemyMap instanceof Object; // truemyMap instanceof String; // falseObject.create() で生成されたオブジェクト
次の例では、instanceof をObject.create() で生成したオブジェクトに使用した場合の動作を示しています。
function Shape() {}function Rectangle() { Shape.call(this); // スーパークラスのコンストラクターを呼び出す}Rectangle.prototype = Object.create(Shape.prototype);Rectangle.prototype.constructor = Rectangle;const rect = new Rectangle();rect instanceof Object; // truerect instanceof Shape; // truerect instanceof Rectangle; // truerect instanceof String; // falseconst literalObject = {};const nullObject = Object.create(null);nullObject.name = "My object";literalObject instanceof Object; // true : すべてのオブジェクトリテラルは Object.prototype をプロトタイプとして持つ({}) instanceof Object; // true : 上記と同じnullObject instanceof Object; // false : プロトタイプはプロトタイプチェーンの末尾 (null)myCar が Car 型および Object 型であることを示す
以下のコードは、Car オブジェクト型とそのインスタンスであるmyCar を生成しています。instanceof 演算子で、myCar はCar 型およびObject 型であることを示します。
function Car(make, model, year) { this.make = make; this.model = model; this.year = year;}const myCar = new Car("Honda", "Accord", 1998);const a = myCar instanceof Car; // true を返すconst b = myCar instanceof Object; // true を返すinstanceof の否定
あるオブジェクトが特定のコンストラクターのinstanceof でないことを検査するには、次のようにします。
if (!(myCar instanceof Car)) { // 次のようなことをする // myCar = new Car(myCar)}これは実際には次のものとは異なります。
if (!myCar instanceof Car) { // ここには到達しない}これは常にfalse になります。(!myCar はinstanceof の前に評価されるため、常に論理値がCar のインスタンスであるかどうかを検査しようとします。)
instanceof の動作のオーバーライド
instanceof を使用する際のよくある落とし穴は、x instanceof C が真の場合、x がC をコンストラクターとして作成されたと信じることです。これは真ではありません。なぜなら、x はプロトタイプとしてC.prototype を直接割り当てられて作成される可能性があるからです。この場合、コードがx からC のプライベートフィールドを読み取ろうとしても失敗します。
class C { #value = "foo"; static getValue(x) { return x.#value; }}const x = { __proto__: C.prototype };if (x instanceof C) { console.log(C.getValue(x)); // TypeError: Cannot read private member #value from an object whose class did not declare it}これ避けるために、C にSymbol.hasInstance メソッドを追加してinstanceof の動作を上書きすることができます。これにより、in を使ったブランドチェックをすることができます。
class C { #value = "foo"; static [Symbol.hasInstance](x) { return #value in x; } static getValue(x) { return x.#value; }}const x = { __proto__: C.prototype };if (x instanceof C) { // x は C ではないため、実行されない console.log(C.getValue(x));}この動作を現在のクラスに制限 したいかもしれません。そうしないと、サブクラスで誤検知が発生する可能性があるからです。
class D extends C {}console.log(new C() instanceof D); // true : D は C から [Symbol.hasInstance] を継承しているためこれを行うには、thisが現在のコンストラクターであるかどうかを調べることができます。
class C { #value = "foo"; static [Symbol.hasInstance](x) { return this === C && #value in x; }}class D extends C {}console.log(new C() instanceof D); // falseconsole.log(new C() instanceof C); // trueconsole.log({ __proto__: C.prototype } instanceof C); // false仕様書
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-relational-operators> |