object.getprototypeof 是安全获取对象原型的唯一标准方式,它直接读取内部[[prototype]]槽,避免__proto__被覆盖、污染或禁用导致的错误,返回对象真实原型或null。

Object.getPrototypeOf 是 JavaScript 中安全获取对象原型的唯一标准方式,它绕过对象可能重写的 __proto__ 访问器或污染的属性,直接读取内部 [[Prototype]] 槽。
为什么不能直接访问 __proto__
__proto__ 是非标准但被广泛支持的访问器属性,但它可被对象自身定义覆盖,甚至设为 null 或非对象值。例如:
const obj = { __proto__: "not an object" };
console.log(obj.__proto__); // "not an object"(错误类型)
console.log(Object.getPrototypeOf(obj)); // Object.prototype(正确结果)
- 对象可自行定义
__proto__属性,导致读取失真 - 严格模式下对
__proto__赋值会静默失败或抛错 - 某些环境(如部分 Web Worker 或冻结对象)可能禁用
__proto__
它返回什么,以及边界情况处理
Object.getPrototypeOf(obj) 总是返回对象的内部原型(即 [[Prototype]]),若无原型则返回 null。注意以下常见情形:
- 普通对象:返回其构造函数的
prototype(通常是Object.prototype) - 数组、日期等内置对象:返回对应内置原型(
Array.prototype、Date.prototype等) - 通过
Object.create(null)创建的对象:返回null(无原型链) - 原始值(如字符串字面量):自动装箱后取原型,即
String.prototype
与 instanceof 和 isPrototypeOf 的协作使用
单独获取原型意义有限,常配合其他方法做防御性判断:
- 用
Object.getPrototypeOf(obj) === Array.prototype判断是否为原生数组实例(比Array.isArray更底层,但不推荐替代) - 结合
isPrototypeOf向上遍历原型链:Array.prototype.isPrototypeOf(obj) - 避免依赖
obj.constructor.prototype——该值易被修改,不可靠
在代理(Proxy)和冻结对象中的行为
Object.getPrototypeOf 在多数元操作场景下保持稳定:
- 对
Object.freeze(obj)对象仍能正常获取原型 - 对 Proxy 对象,返回的是 proxy 的目标对象的原型(除非 handler 显式拦截
getPrototypeOftrap) - 若 Proxy handler 返回非法值(如非对象且非 null),会抛出
TypeError
不复杂但容易忽略:只要目标是对象(包括包装对象),Object.getPrototypeOf 就是获取其真实原型链起点的最可靠入口。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











