Object.getPrototypeOf 比 instanceof 和 constructor.name 更可靠,适用于跨执行上下文、constructor 被篡改或需精确匹配原型的场景;通过遍历原型链比对 prototype 实现类型判断,并可封装为高阶函数提升复用性与健壮性。

直接用 Object.getPrototypeOf 判断实例的原型链源头,比 instanceof 更可控、比 constructor.name 更可靠,特别适合处理跨执行上下文(如 iframe)、被篡改过 constructor 或需要精确匹配原型对象的场景。
用原型对象而非构造函数名做判断
Object.getPrototypeOf(obj) 返回对象的内部 [[Prototype]],也就是它的直接原型。只要这个原型是目标类的 prototype 对象(或其继承链上的某一级),就能确认类型归属。这绕过了 constructor 属性可能被覆盖、重写甚至删除的风险。
- 避免写
obj.constructor === MyClass—— 构造函数引用易被修改 - 避免依赖
obj.constructor.name === 'MyClass'—— 名字可伪造,且不支持匿名类/闭包类 - 优先比较
Object.getPrototypeOf(obj) === MyClass.prototype
支持多级原型链匹配
有些类型断言需要识别“是否为某类或其子类的实例”。这时不能只比对第一级原型,而要沿原型链向上查找,直到找到匹配项或到达 null。
- 用循环调用
Object.getPrototypeOf向上遍历 - 每次比较当前原型是否严格等于目标类的
prototype - 遇到
null停止,返回false
function isInstanceOf(obj, Class) {
if (obj == null) return false;
let proto = Object.getPrototypeOf(obj);
while (proto !== null) {
if (proto === Class.prototype) return true;
proto = Object.getPrototypeOf(proto);
}
return false;
}
兼容跨 iframe 或不同 Realm 的情况
在 iframe、Web Worker 或模块隔离环境中,同一个构造函数(如 Array)在不同上下文中是不同引用,instanceof 会失效。但 Object.getPrototypeOf 获取的是当前对象自身的原型,只要原型链中存在对应结构,仍可识别。
- 对内置类型(
Array,Map,Date等),可用toString.call(obj)辅助验证 - 对自定义类,若需跨 Realm 安全判断,建议暴露一个不可枚举、不可配置的标识属性(如
Symbol.toStringTag),再结合原型检查 - 不依赖全局构造函数引用,只依赖对象自身原型结构
封装成可复用的类型断言工具
把核心逻辑封装为高阶函数,支持缓存、扩展和组合,提升健壮性和可读性。
- 预计算目标类的
prototype,避免重复访问 - 支持传入多个类,返回是否匹配任意一个(类似
isOneOf) - 可选开启严格模式:只认直接原型,不沿链查找
- 对
null和原始值提前返回false,避免getPrototypeOf报错
const createIsType = (Class, { strict = false } = {}) => {
const targetProto = Class.prototype;
return obj => {
if (obj == null || typeof obj !== 'object') return false;
let proto = Object.getPrototypeOf(obj);
if (strict) return proto === targetProto;
while (proto !== null) {
if (proto === targetProto) return true;
proto = Object.getPrototypeOf(proto);
}
return false;
};
};

















