原型属性共享的核心在于将属性定义在构造函数的 prototype 上,实例通过 [[prototype]] 链访问同一份属性;实例赋值同名属性会屏蔽原型,引用类型修改影响所有实例但重新赋值不共享。

JavaScript 中原型对象实现属性共享,核心在于把属性定义在构造函数的 prototype 上,而不是在构造函数内部用 this 赋值。这样所有实例访问的是同一份属性,而非各自独立的副本。
为什么原型上的属性能被共享
每个通过构造函数创建的实例,其内部 [[Prototype]](通常可通过 __proto__ 访问)自动指向该构造函数的 prototype 对象。当读取某个属性时,若实例自身没有,引擎会顺着这条链接向上查找——直到在 prototype 上命中,这就完成了“共享”。
- 属性本身存储在原型对象中,内存只分配一次
- 所有实例共用同一个原型引用,不重复创建
- 修改原型上的属性(非覆盖),所有实例立即可见(注意:基本类型值会被隐式包装,实际效果需谨慎验证)
正确添加共享属性的写法
直接给构造函数的 prototype 赋值或添加属性:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
function Car(brand) {
this.brand = brand; // 实例独有属性
}
Car.prototype.color = 'white'; // 所有 Car 实例共享 color 属性
Car.prototype.wheels = 4; // 同样共享
const car1 = new Car('Toyota');
const car2 = new Car('Honda');
console.log(car1.color); // 'white'
console.log(car2.color); // 'white'
console.log(car1.color === car2.color); // true(引用同一值)
哪些情况会导致“看似共享、实则不共享”
虽然属性定义在 prototype 上,但某些操作会破坏共享效果:
- 实例自身赋值同名属性(如
car1.color = 'red'),会屏蔽原型上的color,后续读取走的是实例属性,不再是原型属性 - 对原型上的引用类型属性(如数组、对象)做修改(
Car.prototype.features.push('ABS')),确实影响所有实例;但若重新赋值(Car.prototype.features = []),新数组只更新原型,已存在的实例仍持有旧引用 - ES6 类语法中,类体内的字段声明(
class C { x = 1 })属于实例属性,不是原型属性,不共享
如何验证属性是否来自原型
可用 hasOwnProperty() 和 in 操作符区分来源:
-
car1.hasOwnProperty('color')→false(说明 color 不在实例上) -
'color' in car1→true(说明可通过原型链访问到) -
Object.getPrototypeOf(car1) === Car.prototype→true
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










