instanceof

instanceof 演算子は、オブジェクトが自身のプロトタイプにコンストラクタの prototype プロパティを持っているかを確認します。戻り値はブール値です。

構文

object instanceof constructor

引数

object
確認するオブジェクト
constructor
オブジェクトに対して確認を行う関数

説明

instanceof 演算子は、object のプロトタイプチェインで constructor.prototype の存在を確認します。

// コンストラクタを定義
function C() {}
function D() {}

let 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 だから

C.prototype = {}
let o2 = new C()

o2 instanceof C; // true

// false C.prototype は o のプロトタイプチェーンの
// どこにも存在しない
o instanceof C;

D.prototype = new C(); // 継承を使用
let o3 = new D()
o3 instanceof D; // true
o3 instanceof C; // true o3 のプロトタイプチェーンに C.prototype があるため。

注意事項: instanceof による確認結果はコンストラクタの prototype プロパティの変化に従って変わることがあります。また、オブジェクトのプロトタイプを Object.setPrototypeOf を用いて変更した場合や、非標準の __proto__ 疑似プロパティを用いた場合も変わりえます。

instanceof と複数のコンテキスト (例: frame や window)

異なるスコープは、別々の実行環境を持ちます。つまり、それらは別々の組み込み物 (別々のグローバルオブジェクト、別々のコンストラクタ 等々) を持ちます。これにより予期せぬ結果になる場合があります。例えば、[] instanceof window.frames[0].Array は、Array.prototype !== window.frames[0].Array であることおよび配列が以前から継承していることから false を返します。

これは、始めはわかりにくいかもしれませんが、スクリプトで複数のフレームやウィンドウを扱い始め、オブジェクトをあるコンテキストから別のコンテキストへ関数を経由して渡すようになると、正当かつ重要な事項になります。例えば、Array.isArray(myObj) を使用して、与えられたオブジェクトが実際に配列であるかどうかを安全にチェックできます。

例えば、別のコンテキストで NodesSVGElement であるかどうかをチェックするには、myNode instanceof myNode.ownerDocument.defaultView.SVGElement を使用します。

Mozilla 開発者への注意点

XPCOM を用いるコードでは instanceof に特別な効果があります: obj instanceof xpcomInterface (例えば Components.interfaces.nsIFile) は obj.QueryInterface(xpcomInterface) を呼び出し、QueryInterface が成功した場合に true を返します。

このような呼び出しの副作用として、instanceof による確認の成功後に objxpcomInterface のプロパティを利用できることがあります。標準 JavaScript の環境と異なり、obj が異なるスコープ由来であっても obj instanceof xpcomInterface での確認は期待どおりに動作します。

StringDateObject タイプであることの実証

以下のコードは、StringDate オブジェクトが Object タイプでもある (Object から派生している) ことの実証に instanceof を用いています。

また、オブジェクトリテラルを用いて作成されたオブジェクトに対する例外、つまり、prototype が undefined であるにも関わらず instanceof Objecttrue を報告する例を示します。

let simpleStr = 'This is a simple string'
let myString  = new String()
let newStr    = new String('コンストラクターで作成された文字列')
let myDate    = new Date()
let myObj     = {}
let myNonObj  = Object.create(null)

simpleStr instanceof String  // false を返す 文字列リテラルはオブジェクトではありません。
myString  instanceof String  // true を返す
newStr    instanceof String  // true を返す
myString  instanceof Object  // true を返す

myObj    instanceof Object   // true を返す すべてのオブジェクトリテラルはプロトタイプとして Object.prototype を持っています。
({})     instanceof Object   // true を返す 上記と同じ
myNonObj instanceof Object   // false を返す プロトタイプはプロトタイプチェーンの終わりです(null)
myString instanceof Date     // false を返す

myDate instanceof Date      // true を返す
myDate instanceof Object    // true を返す
myDate instanceof String    // false を返す

mycarCar タイプおよび Object タイプであることの実証

以下のコードは、Car オブジェクトタイプとそのインスタンスである mycar を生成しています。instanceof 演算子で、mycarCar タイプおよび Object タイプであることを実証します。

function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
let mycar = new Car('Honda', 'Accord', 1998)
let a = mycar instanceof Car     // true を返す
let b = mycar instanceof Object  // true を返す

インスタンスではないことの実証

オブジェクトが特定のコンストラクタの instanceof でないかどうかを確認するには次のようにします。

if (!(mycar instanceof Car)) {
  // Do something, like:
  // mycar = new Car(mycar)
}

これは実際には次のものとは異なります。

if (!mycar instanceof Car)

これは常に false になります。(!mycarinstanceof の前に評価され、常に Car のインスタンスを確認したブール値になります)。

仕様

仕様書
ECMAScript (ECMA-262)
Relational Operators の定義

ブラウザー実装状況

BCD tables only load in the browser

関連情報