prototype是构造函数的属性,__proto__是实例对象的内部链接,二者由new自动关联而非桥梁关系;前者定义共享方法,后者指向前者构成原型链。

JavaScript 中显式原型 prototype 和隐式原型 __proto__ 并不是“桥梁关系”,而是通过构造函数和实例对象天然关联的两个不同属性。理解它们的关键在于:构造函数拥有 prototype,而实例对象拥有 __proto__,且后者会自动指向前者。
prototype 是构造函数的属性
prototype 是每个函数(包括自定义构造函数)自带的属性,它是一个对象,默认包含一个 constructor 指回该函数。这个对象用于定义所有由该构造函数创建的实例共享的方法和属性。
例如:
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log('Hello, ' + this.name);
};
const p1 = new Person('Alice');
console.log(p1.sayHello()); // Hello, Alice
这里 Person.prototype 就是将来被所有 Person 实例通过原型链访问到的共享原型对象。
__proto__ 是实例对象的内部链接
__proto__(注意是双下划线)是每个对象(除 null)都有的属性,它指向该对象的原型(即它的“父级”原型对象)。对于用 new Constructor() 创建的实例来说,instance.__proto__ 会自动等于 Constructor.prototype。
继续上面的例子:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
console.log(p1.__proto__ === Person.prototype); // true console.log(p1.__proto__.constructor === Person); // true
这就是 JavaScript 原型链工作的核心机制:实例通过 __proto__ 找到构造函数的 prototype,从而复用方法。
不要把 __proto__ 当作“设置 prototype 的桥梁”
__proto__ 是可读写的(不推荐修改),但它不是用来“桥接”或“同步” prototype 的工具。修改 __proto__ 只会影响当前对象的原型链查找路径,不会改变构造函数的 prototype;反之亦然。
- 修改
Person.prototype会影响所有已有和未来的Person实例(只要没被覆盖) - 修改
p1.__proto__只影响p1自身的原型链,不影响其他实例 - 直接给
p1.__proto__ = {}会切断它与Person.prototype的联系
现代替代方案:优先使用 Object.getPrototypeOf / Object.setPrototypeOf
__proto__ 是非标准遗留属性(尽管浏览器普遍支持),ECMAScript 推荐使用标准 API:
-
Object.getPrototypeOf(obj)替代obj.__proto__读取原型 -
Object.setPrototypeOf(obj, proto)替代赋值obj.__proto__ = proto - 创建新对象时,用
Object.create(proto)显式指定原型
例如:
const parent = { greet() { return 'Hi'; } };
const child = Object.create(parent);
console.log(Object.getPrototypeOf(child) === parent); // true
本质上,prototype 和 __proto__ 是原型继承机制的一体两面:一个在构造函数上定义共享行为,一个在实例上建立查找链。它们之间没有需要手动搭建的“桥梁”,而是语言本身在 new 时自动建立的连接。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










