Object.getPrototypeOf(obj)是最安全的方式,它专为获取原型设计,不触发getter、不访问非标准__proto__、不依赖不可靠构造函数链;对null/undefined抛TypeError,对原始值自动装箱后返回对应包装类型原型。

直接用 Object.getPrototypeOf(obj) 就是最安全的方式,它专为此设计,不会触发 getter、不访问 __proto__、也不依赖不可靠的构造函数链。
为什么不用 obj.__proto__?
__proto__ 是非标准属性(虽被广泛支持),且在严格模式下可能不可写;更重要的是,它本身是一个访问器属性,读取时可能意外触发自定义 getter,导致副作用或报错。而 Object.getPrototypeOf 是标准化的反射方法,只读取内部 [[Prototype]],行为稳定可靠。
注意 null 和原始值的边界情况
该方法对 null 或 undefined 会抛出 TypeError;对原始值(如字符串、数字)会自动装箱为对象再取原型,结果是对应包装类型的原型(例如 Object.getPrototypeOf("hello") 返回 String.prototype)。若需严格处理,建议先校验:
- 用
obj != null && typeof obj === 'object'排除 null/undefined/原始值 - 若明确只处理普通对象,可加
!Array.isArray(obj) && !(obj instanceof Date) && !(obj instanceof RegExp)等细化判断
替代方案:Reflect.getPrototypeOf 更现代
ES6 引入的 Reflect.getPrototypeOf(obj) 行为与 Object.getPrototypeOf 完全一致,但语义更清晰——它属于“元编程反射 API”,强调操作的是对象的内部结构。两者性能无差异,选其一即可;团队统一用 Reflect 可提升代码一致性。
避免依赖 constructor.prototype
不要用 obj.constructor && obj.constructor.prototype,因为 constructor 可被篡改,且原型链上中间对象的 constructor 可能指向错误构造函数(例如 Object.create(Foo.prototype) 创建的对象,其 constructor 仍指向 Foo,但原型已是 Foo.prototype 的父级)。Object.getPrototypeOf 直接读取内部链接,不受这些干扰。
不复杂但容易忽略细节:校验输入、避开非标准属性、理解原始值的隐式转换——做到这三点,就能真正安全地获取原型。


















