Object.getPrototypeOf仅返回对象的直接原型,无法直接获取深层祖先类原型的元数据;需逐层调用并配合构造函数比对或属性检查来准确定位目标原型并提取信息。
Object.getPrototypeOf 本身不读取“元数据”,它只返回指定对象的直接原型(即 [[Prototype]] 内部槽指向的对象)。所谓“深层祖先类原型的元数据”,实际需通过**逐层调用 Object.getPrototypeOf 配合属性检查或 Reflect.getPrototypeOf 链式遍历**来间接获取。关键不在“精确读取元数据”,而在于**准确定位目标原型对象并从中提取所需信息**。
Object.getPrototypeOf(obj) 每次只返回 obj 的**直接原型**,不会跳过中间层,也无法自动识别“属于哪个类”或“是否为某祖先类的原型”。例如:
class A {}class B extends A {}class C extends B {}const c = new C();console.log(Object.getPrototypeOf(c) === C.prototype); // trueconsole.log(Object.getPrototypeOf(C.prototype) === B.prototype); // trueconsole.log(Object.getPrototypeOf(B.prototype) === A.prototype); // trueconsole.log(Object.getPrototypeOf(A.prototype) === Object.prototype); // true
要拿到 A.prototype,必须连续调用三次 Object.getPrototypeOf;不能一步到位。
避免硬编码调用次数,推荐用循环 + 构造函数比对或 Symbol.toStringTag 判断:
constructor.name 或 constructor === TargetClass 定位目标原型(注意:构造函数可能被篡改,生产环境建议配合 Object.is 或严格等号)Reflect.getPrototypeOf 更符合规范(与 Object.getPrototypeOf 行为一致,但语义更清晰)null,防止遍历到 Object.prototype 后继续调用报错JavaScript 原型上没有内置“元数据容器”,所谓元数据通常指:
A.prototype.$$meta = { version: '1.2' })——可直接访问A.$$config、A[Symbol.for('desc')])——需从构造函数而非原型读取Object.getOwnPropertyDescriptors 查看原型自身属性描述符(不含继承来的)Object.getOwnPropertyNames + getOwnPropertyDescriptor 批量提取自有属性及其配置以下函数可安全获取某个实例向上查找时第一个匹配构造函数的原型:
function getPrototypeByConstructor(obj, TargetClass) { let proto = Object.getPrototypeOf(obj); while (proto !== null) { if (proto.constructor === TargetClass || proto.constructor?.name === TargetClass.name) { return proto; } proto = Object.getPrototypeOf(proto); } return null;}// 使用const c = new C();const aProto = getPrototypeByConstructor(c, A); // 返回 A.prototypeconsole.log(aProto?.hasOwnProperty('$$meta')); // true(如果定义了)