原型方法只存一份供所有实例共用,而构造函数内定义的方法每次new都会创建新副本,造成内存浪费;class本质仍是原型机制,方法自动挂载到prototype上实现共享。

因为原型上的方法只存一份,所有实例共用;而构造函数里定义的方法,每个实例都生成一个独立副本。
每个实例不再重复创建函数对象
在构造函数中写 this.say = function() {},每次 new Person() 都会新建一个函数对象。100 个实例就产生 100 份完全相同的函数,堆内存白白增加。
- 原型方式:方法挂到
Person.prototype.say,只在内存中存在一次 - 验证很简单:
new Person('a').say === new Person('b').say返回 true - 引擎层面:函数对象本身不被复制,实例仅通过
__proto__链访问它
实例对象更轻量,只保留自有数据
实例自身只需存储真正属于它的状态,比如 this.name、this.age 等原始值或独立引用;方法、通用配置等不变内容全交给原型统一管理。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 实例内存:仅含
name、age等自有属性 - 原型内存:独立存在,含
say、walk等共享成员 - 查找机制:先查实例自身,查不到再沿
__proto__向上找,天然支持“就近优先 + 共享后备”
避免可变引用类型污染,保持内存安全
原型适合放函数和不可变值(如 Person.prototype.species = 'Homo sapiens'),但绝不能放数组、对象等可变引用类型——否则多个实例会意外共享同一份数据,引发隐蔽 bug。
- ❌ 错误:
Person.prototype.hobbies = []→ 一人 push,全员变化 - ✅ 正确:
this.hobbies = []放在构造函数里,确保每个实例拥有独立副本 - 这样既守住内存节省优势,又隔离了实例间的状态
现代写法本质没变,只是更可靠
class 语法是原型链的封装,编译后方法依然落在 prototype 上。它自动维护 constructor,减少手动修复出错可能,但底层共享机制完全一致。
-
class Person { say() { } }等价于Person.prototype.say = function() { } - ES6 class 不改变原型链原理,只是让正确做法更容易落地
- 高频访问属性可缓存到实例自身,避免反复走原型链查找
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










