函数声明挂载到对象原型上是为了让多个实例共享同一份方法代码、节省内存并支撑原型继承机制,必须通过构造函数的prototype属性(如Person.prototype.sayHi)或ES6 class自动挂载,而非在构造函数内赋值给this。

函数声明挂载到对象原型上,核心目的是让多个实例共享同一份方法代码,避免重复创建、节省内存,同时支撑原型继承机制。这不是语法糖,而是 JavaScript 原型链工作的底层基础。
挂载方式:明确区分位置与时机
不能把函数写在构造函数内部再赋给 this,那样每个实例都会生成独立副本。正确做法是直接附加到构造函数的 prototype 属性上:
- 使用点语法:
Person.prototype.sayHi = function() { ... }; - 使用方括号语法(适合动态键名):
Person.prototype['logInfo'] = function() { ... }; - ES6 class 中定义的普通方法(非 static、非箭头、非字段赋值),自动挂到类的 prototype 上,等价于手动挂载
为什么必须挂到 prototype 而不是实例上
挂到 prototype 是为了让所有实例通过原型链访问同一函数对象:
-
new Person('A').sayHi === new Person('B').sayHi返回 true,说明是同一个函数引用 - 实例自身没有
sayHi属性,但能调用,是因为引擎沿__proto__向上查找到Person.prototype - 若在 constructor 里写
this.sayHi = function() {...},则每个实例都持有一份新函数,===判断为 false
挂载内容有明确边界
prototype 适合放**可安全共享**的内容:
立即学习“Java免费学习笔记(深入)”;
- ✅ 函数方法(最典型用途)
- ✅ 不可变的默认值,如
Animal.prototype.species = 'Mammal'; - ❌ 不要挂可变引用类型,如
Animal.prototype.tags = [];—— 所有实例会共用这个数组,一处修改处处生效 - ⚠️ 挂载后记得检查
constructor是否仍指向原构造函数,尤其批量重写prototype时
作用不止于节省内存
挂载到 prototype 的函数承担着更关键的角色:
- 构成实例的“公共能力集”,是面向对象行为复用的实现路径
- 支撑继承:子类可通过
Object.setPrototypeOf(Child.prototype, Parent.prototype)或extends接入父类方法 - 允许运行时动态增强:比如给内置构造函数(如 Array)的 prototype 添加自定义方法(需谨慎)
- 使
instanceof和isPrototypeOf()等判断机制正常工作


















