JavaScript如何判断一个对象是否继承自另一个对象?

65 阅读2分钟

在 JavaScript 中,判断一个对象是否继承自另一个对象(即是否位于其原型链上)可以通过以下几种方法实现:

1. 使用 instanceof 操作符

语法object instanceof Constructor
作用:检查 object 的原型链中是否存在 Constructor.prototype

function Animal() {}
function Dog() {}
Dog.prototype = new Animal(); // Dog 继承自 Animal

const dog = new Dog();
console.log(dog instanceof Dog);     // true
console.log(dog instanceof Animal);  // true(因为 Dog 继承自 Animal)
console.log(dog instanceof Object);  // true(所有对象都继承自 Object)

注意

  • instanceof 右侧必须是构造函数(如 Animal),不能直接是对象实例。
  • 对于跨窗口(iframe)的对象,可能会因构造函数不同而失效。

2. 使用 Object.prototype.isPrototypeOf()

语法prototypeObj.isPrototypeOf(object)
作用:检查 prototypeObj 是否存在于 object 的原型链中。

const animal = { type: "Animal" };
const dog = Object.create(animal); // dog 继承自 animal

console.log(animal.isPrototypeOf(dog)); // true
console.log(Object.prototype.isPrototypeOf(dog)); // true(Object 是顶层原型)

优势

  • 直接以对象为参数,无需构造函数。
  • 跨窗口对象也能正常工作(只要原型关系存在)。

3. 手动遍历原型链(递归或循环)

通过 Object.getPrototypeOf() 逐级检查原型链:

function isPrototypeOf(prototypeObj, obj) {
  let currentProto = Object.getPrototypeOf(obj);
  while (currentProto !== null) {
    if (currentProto === prototypeObj) return true;
    currentProto = Object.getPrototypeOf(currentProto);
  }
  return false;
}

// 示例
const animal = { type: "Animal" };
const dog = Object.create(animal);

console.log(isPrototypeOf(animal, dog)); // true
console.log(isPrototypeOf(Object.prototype, dog)); // true

4. 使用 Object.getPrototypeOf() 直接比较

若明确知道继承层级,可以直接比较原型:

function Animal() {}
function Dog() {}
Dog.prototype = new Animal();

const dog = new Dog();
console.log(Object.getPrototypeOf(dog) === Dog.prototype); // true
console.log(Object.getPrototypeOf(Dog.prototype) === Animal.prototype); // true

对比与选择

方法适用场景注意事项
instanceof判断对象是否由某个构造函数创建依赖构造函数,跨窗口可能失效
isPrototypeOf()判断对象是否继承自另一个对象直接使用原型对象,跨窗口安全
手动遍历原型链自定义复杂判断逻辑需处理原型链终点 null
Object.getPrototypeOf()精确比较原型层级需明确知道继承结构

特殊情况处理

  1. 继承自 null 的对象
const obj = Object.create(null); // 无原型链
console.log(obj instanceof Object); // false
console.log(Object.prototype.isPrototypeOf(obj)); // false
  1. 类继承(ES6 Class)
class Animal {}
class Dog extends Animal {}
const dog = new Dog();
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true
  1. 跨窗口对象
// 在 iframe 中创建的数组
const iframeArray = window.frames[0].Array(1, 2);
console.log(iframeArray instanceof Array); // false(不同窗口的 Array)
console.log(Array.prototype.isPrototypeOf(iframeArray)); // false
console.log(Object.prototype.isPrototypeOf(iframeArray)); // true(顶层原型相同)

总结

  • 优先使用 instanceof:当需要判断对象是否由某个构造函数创建时。
  • 使用 isPrototypeOf() :当需要直接基于原型对象判断继承关系时(如 Object.create() 创建的对象)。
  • 手动遍历:当需要自定义判断逻辑或处理复杂继承结构时。

通过这些方法,可以准确判断 JavaScript 中对象间的继承关系。