instanceof 运算符

instanceof 判断右边构造器的 prototype 是否出现在左边对象的原型链上,本质是原型关系判断。

#type / concept #status / evergreen #resource / javascript #resource / ecmascript

[!info] related notes

instanceof 运算符

一句话定义

instanceof 判断的是”右边构造函数的 prototype,是否出现在左边对象的原型链上”——本质是原型链查找,不是底层类型判断。

用法

[] instanceof Array        // true
[] instanceof Object       // true(原型链上能找到 Object.prototype)
new Date() instanceof Date // true

原理

等价于沿原型链向上查找:

function myInstanceof(obj, Constructor) {
  if (obj == null || (typeof obj !== 'object' && typeof obj !== 'function')) {
    return false;
  }
  const prototype = Constructor.prototype;
  let proto = Object.getPrototypeOf(obj);
  while (proto !== null) {
    if (proto === prototype) return true;
    proto = Object.getPrototypeOf(proto);
  }
  return false;
}

继承关系

function Person() {}
const p = new Person();

p instanceof Person // true  (p.__proto__ === Person.prototype)
p instanceof Object // true  (Person.prototype.__proto__ === Object.prototype)

不适用场景

1. 不能判断原始类型

123 instanceof Number      // false
'abc' instanceof String    // false

原始值不是对象,不走原型链。

new Number(123) instanceof Number // true(包装对象)

2. 跨 realm / 跨 iframe 失效

不同 iframe 有独立的全局环境和构造函数:

const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
const iframeArray = iframe.contentWindow.Array();

iframeArray instanceof Array                       // false
iframeArray instanceof iframe.contentWindow.Array  // true

解决方案:用 Array.isArray()Object.prototype.toString.call()

3. 可被 Symbol.hasInstance 干预

class MyClass {
  static [Symbol.hasInstance](obj) {
    return obj && obj.flag === true;
  }
}

({ flag: true }) instanceof MyClass // true

instanceof 不是绝对客观的底层判断,而是一个可定制协议。

适用场景

  • 自定义类实例判断:err instanceof Error
  • 同一 realm 内判断构造器关系:promise instanceof Promise
创建于 2026/4/1 更新于 2026/5/27