最推荐使用 object.getprototypeof() 获取对象原型,它标准化、语义清晰、兼容性好;__proto__ 非标准且不推荐用于生产;constructor.prototype 是构造函数的原型定义,而 object.getprototypeof(instance) 才是实例当前实际原型。

在 JavaScript 中,获取对象的原型引用有几种标准方式,最常用、最推荐的是使用 Object.getPrototypeOf() 方法。
使用 Object.getPrototypeOf()
这是 ES5 引入的标准化方法,适用于所有对象(包括普通对象、数组、函数、内置对象等),且语义清晰、行为可靠:
- 推荐首选:它明确表达“我要获取这个对象的 [[Prototype]]”的意图;
- 兼容性好:现代浏览器和 Node.js 环境均支持;
- 不会受
obj.__proto__被修改或不可写的影响(__proto__是非标准但广泛支持的访问器)。
示例:
const obj = {};
console.log(Object.getPrototypeOf(obj) === Object.prototype); // true
const arr = [];
console.log(Object.getPrototypeOf(arr) === Array.prototype); // true
function Foo() {}
const f = new Foo();
console.log(Object.getPrototypeOf(f) === Foo.prototype); // true
通过 __proto__ 属性(不推荐用于生产)
obj.__proto__ 是一个非标准但被几乎所有引擎支持的访问器属性,它直接暴露内部 [[Prototype]] 链:
- 可读可写(但修改可能带来性能或兼容性问题);
- 不是语言规范要求的,ECMAScript 标准中只定义了
[[Prototype]]内部槽和Object.getPrototypeOf等操作; - 在严格模式下对不可写
__proto__赋值会静默失败或抛错,行为不一致。
仅建议在调试、学习或临时脚本中使用,避免写入生产代码。
构造函数的 prototype 属性 ≠ 实例的原型
注意区分两个易混淆概念:
-
Constructor.prototype是**构造函数的 prototype 属性**,它定义了将来由该构造函数创建的实例的原型; -
Object.getPrototypeOf(instance)才是**实例当前实际指向的原型对象**(通常就是Constructor.prototype,但可通过Object.setPrototypeOf或__proto__修改)。
例如:
function Bar() {}
const b = new Bar();
console.log(Object.getPrototypeOf(b) === Bar.prototype); // true(默认情况)
// 修改后不再相等
Object.setPrototypeOf(b, null);
console.log(Object.getPrototypeOf(b)); // null
特殊对象的原型获取
某些对象没有原型(即 [[Prototype]] 为 null),调用 Object.getPrototypeOf 会返回 null:
-
Object.create(null)创建的对象; - 通过
Object.setPrototypeOf(obj, null)显式断开原型链的对象; - 原始值(如字符串、数字)会被自动包装,其包装对象的原型仍可获取,但原始值本身无原型(不能直接对其调用
getPrototypeOf,会报错)。
安全做法:使用前检查是否为对象类型:
function safeGetProto(value) {
if (value != null && typeof value === 'object') {
return Object.getPrototypeOf(value);
}
return null;
}
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











