标准答案

  1. instanceof 判断的是对象原型链上是否能找到右侧构造函数的 prototype。
  2. 左侧是 null、undefined 或基本类型时,通常直接返回 false。
  3. 从 Object.getPrototypeOf(left) 开始向上查找,直到 null 为止。
  4. 某一层原型严格等于 Constructor.prototype 时返回 true。
  5. 要注意 Symbol.hasInstance、跨 realm 对象和手动改 prototype 等真实环境细节。

题目解析

instanceof 不是判断“构造函数名字是否相同”,也不是检查对象上有没有某个属性。它关注的是原型链关系。

手写实现时要从实例的原型开始查,而不是拿实例对象本身直接和 Constructor.prototype 比。因为实例对象通常不是构造函数的 prototype,它的上一层原型才是。

真实场景下 instanceof 也有边界。数组跨 iframe 可能因为构造函数来自不同 realm 而判断失败;对象的原型可以被手动修改;类还可以通过 Symbol.hasInstance 自定义行为。

代码示例

简化版实现可以展示原型链向上查找的过程。

JavaScript
function myInstanceof(value, Constructor) {
  if (value === null || (typeof value !== 'object' && typeof value !== 'function')) {
    return false
  }

  let proto = Object.getPrototypeOf(value)
  const target = Constructor.prototype

  while (proto) {
    if (proto === target) return true
    proto = Object.getPrototypeOf(proto)
  }

  return false
}

常见误区

  • 把 instanceof 理解成比较 constructor 属性,忽略 constructor 可以被改写。
  • 从 value 本身开始比较,漏掉应该从 Object.getPrototypeOf(value) 开始。
  • 忘记处理 null 和基本类型。

作者信息