instanceof运算符用于测试构造函数的prototype属性是否出现在对象的原型链中的任何位置

The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.

## 语法

    object instanceof constructor

### 参数

`object`
  要检测的对象.

`constructor`
  某个构造函数

## 描述

`instanceof` 运算符用来检测 `constructor.prototype` 是否存在于参数 `object` 的原型链上。

    // 定义构造函数
    function C(){}
    function D(){}

    var o = new C();

    o instanceof C; // true，因为 Object.getPrototypeOf(o) === C.prototype

    o instanceof D; // false，因为 D.prototype不在o的原型链上

    o instanceof Object; // true,因为Object.prototype.isPrototypeOf(o)返回true
    C.prototype instanceof Object // true,同上

    C.prototype = {};
    var o2 = new C();

    o2 instanceof C; // true

    o instanceof C; // false,C.prototype指向了一个空对象,这个空对象不在o的原型链上.

    D.prototype = new C(); // 继承
    var o3 = new D();
    o3 instanceof D; // true
    o3 instanceof C; // true 因为C.prototype现在在o3的原型链上

需要注意的是，如果表达式 `obj instanceof Foo` 返回`true`，则并不意味着该表达式会永远返回`true`，因为`Foo.prototype`属性的值有可能会改变，改变之后的值很有可能不存在于`obj`的原型链上，这时原表达式的值就会成为`false`。另外一种情况下，原表达式的值也会改变，就是改变对象`obj`的原型链的情况，虽然在目前的ES规范中，我们只能读取对象的原型而不能改变它，但借助于非标准的`__proto__`伪属性，是可以实现的。比如执行`obj.__proto__ = {}`之后，`obj instanceof Foo`就会返回`false`了。

### `instanceof`和多全局对象(多个frame或多个window之间的交互)

在浏览器中，我们的脚本可能需要在多个窗口之间进行交互。多个窗口意味着多个全局环境，不同的全局环境拥有不同的全局对象，从而拥有不同的内置类型构造函数。这可能会引发一些问题。比如，表达式 `[] instanceof window.frames[0].Array` 会返回`false`，因为 `Array.prototype !== window.frames[0].Array.prototype`，并且数组从前者继承。

起初，你会认为这样并没有意义，但是当你在你的脚本中开始处理多个frame或多个window以及通过函数将对象从一个窗口传到另一个窗口时，这就是一个有效而强大的话题。比如，实际上你可以通过使用 `Array.isArray(myObj)` 或者`Object.prototype.toString.call(myObj) === "[object Array]"`来安全的检测传过来的对象是否是一个数组。

比如检测一个`Nodes`在另一个窗口中是不是`SVGElement`，你可以使用`myNode instanceof myNode.ownerDocument.defaultView.SVGElement`

Mozilla开发者注意:
在代码中使用 XPCOM `instanceof` 有特殊影响: 如果查询接口成功执行后，`obj instanceof` `xpcomInterface` (e.g. `Components.interfaces.nsIFile`) 调用`obj.QueryInterface(xpcomInterface)` 并且返回 `true` 。这种调用的副作用是在一次成功的`instanceof`测试后，你可以在`obj`上使用`xpcomInterface`的属性。这与标准的`JavaScript`全局变量不同，即使`obj`来自不同的作用域， `obj instanceof xpcomInterface`也可以按预期产生作用。

## 示例

### 演示`String`对象和`Date`对象都属于`Object`类型和一些特殊情况

下面的代码使用了`instanceof`来证明：`String和` `Date`对象同时也属于`Object`类型（他们是由`Object`类派生出来的）。

但是，使用对象文字符号创建的对象在这里是一个例外：虽然原型未定义，但instanceof Object返回true。

    var simpleStr = "This is a simple string";
    var myString  = new String();
    var newStr    = new String("String created with constructor");
    var myDate    = new Date();
    var myObj     = {};
    var myNonObj  = Object.create(null);

    simpleStr instanceof String; // 返回 false, 检查原型链会找到 undefined
    myString  instanceof String; // 返回 true
    newStr    instanceof String; // 返回 true
    myString  instanceof Object; // 返回 true

    myObj instanceof Object;    // 返回 true, 尽管原型没有定义
    ({})  instanceof Object;    // 返回 true, 同上
    myNonObj instanceof Object; // 返回 false, 一种创建对象的方法，这种方法创建的对象不是Object的一个实例

    myString instanceof Date; //返回 false

    myDate instanceof Date;     // 返回 true
    myDate instanceof Object;   // 返回 true
    myDate instanceof String;   // 返回 false

### 演示`mycar`属于`Car`类型的同时又属于`Object`类型

下面的代码创建了一个类型`Car`，以及该类型的对象实例`mycar`. `instanceof`运算符表明了这个`mycar`对象既属于`Car`类型，又属于`Object`类型。

    function Car(make, model, year) {
      this.make = make;
      this.model = model;
      this.year = year;
    }
    var mycar = new Car("Honda", "Accord", 1998);
    var a = mycar instanceof Car;    // 返回 true
    var b = mycar instanceof Object; // 返回 true

### 不是一个实例

要测试对象是否不是特定构造函数的实例，你可以这样做

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

下面代码完全不同

    if (!mycar instanceof Car)

这将永远是假的（`!mycar`将在`instanceof`之前被处理，所以你总是验证布尔值是否是Car的一个实例）。

## 规范

Specification | Status | Comment
--- | --- | ---
ECMAScript Latest Draft (ECMA-262) Relational Operators | Draft |
ECMAScript 2015 (6th Edition, ECMA-262) Relational Operators | Standard |
ECMAScript 5.1 (ECMA-262) The instanceof operator | Standard |
ECMAScript 3rd Edition (ECMA-262) The instanceof operator | Standard | Initial definition. Implemented in JavaScript 1.4.

## 浏览器兼容

The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.

Update compatibility data on GitHub

| Desktop | Mobile | Server
| Chrome | Edge | Firefox | Internet Explorer | Opera | Safari | Android webview | Chrome for Android | Edge Mobile | Firefox for Android | Opera for Android | Safari on iOS | Samsung Internet | Node.js
`instanceof` | Chrome Full support Yes | Edge Full support Yes | Firefox Full support 1 | IE Full support Yes | Opera Full support Yes | Safari Full support Yes | WebView Android Full support Yes | Chrome Android Full support Yes | Edge Mobile Full support Yes | Firefox Android Full support 4 | Opera Android Full support Yes | Safari iOS Full support Yes | Samsung Internet Android Full support Yes | nodejs Full support Yes

### Legend

Full support
  Full support

## 相关链接

- typeof
- `Symbol.hasInstance`