结论是把方法挂到构造函数的prototype上,所有实例共用同一份函数代码,避免重复创建;因实例内定义方法会为每个实例生成独立函数副本,而原型上定义的方法通过__proto__链共享,zhangsan.sayhello === lisi.sayhello为true。

直接说结论:把方法挂到构造函数的 prototype 上,所有实例共用同一份函数代码,避免每个实例都单独存一份——这才是真正节省内存的关键。
为什么实例内定义方法会浪费内存
每次用 new 创建对象时,如果方法写在构造函数内部,JavaScript 就会为每个实例重新生成一个函数副本:
this.sayHello = function() { console.log('hi') };- 哪怕创建 1000 个实例,就有 1000 个独立的
sayHello函数对象 - 函数本质是对象,每份都占用堆内存,且无法复用
-
zhangsan.sayHello === lisi.sayHello返回false,说明它们根本不是同一个函数
原型上挂方法:一份代码,千人共用
把方法统一放到 Constructor.prototype 上,所有实例通过原型链访问它:
Person.prototype.sayHello = function() { console.log('hi') };- 无论创建多少个
new Person(),sayHello只在内存中存在一次 - 所有实例调用的都是同一个函数引用:
zhangsan.sayHello === lisi.sayHello是true - 实例本身不存方法,只存自己的数据(如
name、age),轻量干净
原型链让共享成为可能
每个实例内部都有一个隐式链接 __proto__,它自动指向其构造函数的 prototype:
-
zhangsan.__proto__ === Person.prototype→ 成立 - 当调用
zhangsan.sayHello(),引擎先查实例自身,没找到就顺着__proto__找到Person.prototype上的方法 - 这个查找过程天然支持共享,无需额外配置
- 最终整条链终点是
Object.prototype.__proto__ === null,结构清晰可控
实际怎么操作才规范
记住两个分工原则,代码既高效又易维护:
- 实例专属数据(如用户名、ID)写在构造函数里:
this.name = name - 所有实例通用的行为(如验证、格式化、交互逻辑)一律挂到
prototype上 - 避免混用:不要在构造函数里重复定义和原型同名的方法,否则实例上的会屏蔽原型上的(就近原则)
- 现代开发中推荐用
Object.getPrototypeOf(obj)替代__proto__,更标准、更安全
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











