结论:将方法挂到构造函数的 prototype 上可实现所有实例共享同一份函数体,节省内存、降低开销;因构造函数内定义方法会导致每实例创建独立副本,而原型链通过 proto 查找 prototype 上的方法,确保函数只存储一份。

直接说结论:把方法挂到 构造函数的 prototype 上,所有实例共用同一份函数体,不重复创建,自然节省内存、降低开销。
为什么在构造函数里定义方法会浪费内存
每次 new 一个实例,如果方法写在构造函数内部(比如 this.say = function() {...}),JavaScript 就会为这个实例单独生成一份函数副本。100 个实例,就有 100 份相同的 say 函数代码,占用堆空间,还拖慢初始化速度。
- 函数是对象,每次声明都分配独立内存地址
- 这些副本内容完全一样,纯属冗余
- 实例越多,浪费越明显,尤其在高频创建场景(如渲染列表项、事件处理器)
原型链如何实现“一份代码、多处调用”
构造函数自带 prototype 属性,它指向一个普通对象;每个实例内部的 __proto__ 自动指向这个 prototype。当调用 instance.method() 时:
- 先查实例自身有没有
method - 没有 → 沿
__proto__找到Constructor.prototype - 在那里找到方法 → 执行,且
this仍指向当前实例
也就是说,函数只存一次,所有实例共享引用,内存只占一份。
关键操作:方法和属性要分开放
不是所有东西都适合放 prototype,得按“变与不变”来分:
-
不变的方法(如
toString、save、validate)→ 放Constructor.prototype -
每个实例独有的数据(如
name、id、status)→ 在构造函数里用this.xxx = xxx初始化 - 避免把可变对象(如数组、对象)放 prototype,否则所有实例会共用同一个引用,互相干扰
一个小验证:看函数是否真共享
可以这样确认:
function User(name) { this.name = name; }
User.prototype.greet = function() { return `Hi, ${this.name}`; };
const a = new User('Alice');
const b = new User('Bob');
console.log(a.greet === b.greet); // true —— 同一个函数引用
console.log(a.greet.toString() === b.greet.toString()); // true
输出 true 就说明没重复创建,内存确实省了。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











