在 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() | 精确比较原型层级 | 需明确知道继承结构 |
特殊情况处理
- 继承自
null的对象
const obj = Object.create(null); // 无原型链
console.log(obj instanceof Object); // false
console.log(Object.prototype.isPrototypeOf(obj)); // false
- 类继承(ES6 Class)
class Animal {}
class Dog extends Animal {}
const dog = new Dog();
console.log(dog instanceof Dog); // true
console.log(dog instanceof Animal); // true
- 跨窗口对象
// 在 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 中对象间的继承关系。