Object.prototype.isPrototypeOf()

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

isPrototypeOf() 方法用于检查一个对象是否存在于另一个对象的原型链中。

备注: isPrototypeOf()instanceof 运算符不同。在表达式 object instanceof AFunction 中,会检查 object 的原型链是否与 AFunction.prototype 匹配,而不是与 AFunction本身匹配。

尝试一下

function Foo() {}
function Bar() {}

Bar.prototype = Object.create(Foo.prototype);

const bar = new Bar();

console.log(Foo.prototype.isPrototypeOf(bar));
// Expected output: true
console.log(Bar.prototype.isPrototypeOf(bar));
// Expected output: true

语法

js
isPrototypeOf(object)

参数

object

要搜索其原型链的对象。

返回值

一个布尔值,指示调用 isPrototypeOf() 方法的对象(即 this)是否位于 object 的原型链中。当 object 不是一个对象(即基本类型)时,直接返回 false

报错

TypeError

如果 prototypeObj 为 undefined 或 null,会抛出 TypeError

描述

所有继承自 Object.prototype 的对象(即除了 null 原型对象之外的所有对象)都继承了 isPrototypeOf() 方法。该方法允许你检查对象是否存在于另一个对象的原型链中。如果作为参数的 object 不是对象(即基本类型),则该方法直接返回 false。否则,this 值被转换为对象,并且在 object 的原型链中搜索 this 值,直到到达链的末端或找到 this 值为止。

示例

使用 isPrototypeOf()

本示例展示了 Baz.prototypeBar.prototypeFoo.prototypeObject.prototype 存在于对象 baz 的原型链中:

js
class Foo {}
class Bar extends Foo {}
class Baz extends Bar {}

const foo = new Foo();
const bar = new Bar();
const baz = new Baz();

// 原型链:
// foo: Foo --> Object
// bar: Bar --> Foo --> Object
// baz: Baz --> Bar --> Foo --> Object
console.log(Baz.prototype.isPrototypeOf(baz)); // true
console.log(Baz.prototype.isPrototypeOf(bar)); // false
console.log(Baz.prototype.isPrototypeOf(foo)); // false
console.log(Bar.prototype.isPrototypeOf(baz)); // true
console.log(Bar.prototype.isPrototypeOf(foo)); // false
console.log(Foo.prototype.isPrototypeOf(baz)); // true
console.log(Foo.prototype.isPrototypeOf(bar)); // true
console.log(Object.prototype.isPrototypeOf(baz)); // true

isPrototypeOf() 方法以及 instanceof 运算符在处理从特定原型链继承的对象时非常有用,例如,为了保证该对象上存在特定的方法或属性。

例如,如果只有当 baz 对象的原型链中包含 Foo.prototype 时才能执行某些代码,可以这样实现:

js
if (Foo.prototype.isPrototypeOf(baz)) {
  // 执行安全操作
}

然而,Foo.prototype 存在于 baz 的原型链中并不意味着 baz 是使用 Foo 作为其构造函数创建的。例如,baz 可以直接将 Foo.prototype 作为其原型。在这种情况下,如果你的代码从 baz 中读取 Foo私有属性,它仍然会失败:

js
class Foo {
  #value = "foo";
  static getValue(x) {
    return x.#value;
  }
}

const baz = { __proto__: Foo.prototype };

if (Foo.prototype.isPrototypeOf(baz)) {
  console.log(Foo.getValue(baz)); // TypeError: Cannot read private member #value from an object whose class did not declare it
}

对于 instanceof 也是同样的情况。如果你需要以安全的方式读取私有属性,可以提供一个使用 in 运算符的特定类型检查(branded check)方法。

js
class Foo {
  #value = "foo";
  static getValue(x) {
    return x.#value;
  }
  static isFoo(x) {
    return #value in x;
  }
}

const baz = { __proto__: Foo.prototype };

if (Foo.isFoo(baz)) {
  // 不会运行,因为 baz 不是 Foo
  console.log(Foo.getValue(baz));
}

规范

Specification
ECMAScript® 2025 Language Specification
# sec-object.prototype.isprototypeof

浏览器兼容性

BCD tables only load in the browser

参见