javascript中原型实现属性和方法共享的核心是将它们定义在构造函数的prototype上,使所有实例通过__proto__指向同一原型对象,从而共用内存中的同一份数据或函数。

JavaScript 中原型实现属性和方法共享,核心在于把它们放在构造函数的 prototype 对象上,而不是写在构造函数内部。这样所有实例通过隐式原型链(__proto__)指向同一个原型对象,自然共用其中的内容。
为什么 prototype 上的属性能被所有实例共享
每个函数创建时,JS 引擎自动为其生成一个 prototype 属性,它指向一个普通对象——这个对象就是“共享池”。用 new 创建实例时,该实例的 __proto__ 会被自动设为指向这个 prototype。因此,所有实例都链接到同一块内存区域,读取或调用时访问的是同一份数据或函数。
- 方法定义在
prototype上:所有实例共用一份函数代码,节省内存 - 引用类型属性(如数组、对象)放在
prototype上:所有实例操作的是同一个对象,会相互影响 - 基本类型属性(如字符串、数字)放在
prototype上:可读取共享值,但赋值时会在实例自身创建新属性,不破坏共享
方法共享的标准写法
把方法挂到 prototype 是最常见也最推荐的做法。这样既避免重复创建函数,又保证 this 正确指向调用它的实例。
- 错误写法:在构造函数里用
this.sayHi = function() {...}→ 每个实例都有独立副本 - 正确写法:
Person.prototype.sayHi = function() { console.log('Hi, I am ' + this.name); }; - 验证方式:
p1.sayHi === p2.sayHi返回true,说明是同一个函数引用
属性共享要注意可变状态
原型上的属性如果是引用类型(比如 friends: []),所有实例会共用这个数组。一个实例 push 数据,其他实例也会看到变化——这通常不是想要的效果。
- 想让每个实例有独立副本:在构造函数里用
this.friends = [] - 想真正共享配置或常量:可以用
Person.prototype.version = '1.0'或Person.prototype.MAX_RETRY = 3 - 想共享不可变数据(如默认配置对象):建议用
Object.freeze()防止意外修改
原型链查找机制保障了共享可用性
当你访问实例的某个属性或方法时,JS 先查实例自身;没找到就顺着 __proto__ 去原型对象找;还没找到就继续往上,直到 Object.prototype,最后是 null。这个过程让共享成为默认行为。
-
p1.toString()能用,是因为它最终在Object.prototype上找到 -
p1.sayHi()能用,是因为它在Person.prototype上找到 - 如果实例自己定义了同名属性,就会屏蔽原型上的,优先使用自身的
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











