原型上定义方法能节省内存,因为所有实例共享同一份函数对象,避免构造函数内重复创建;正确做法是通过person.prototype.methodname=或重写prototype并修复constructor;实例属性优先于原型成员。

在JavaScript中,把方法定义在构造函数内部会导致每个实例都拥有独立的函数副本,浪费内存;而将方法挂载到构造函数的 prototype 上,能让所有实例共享同一份方法,显著节省内存。
为什么原型上定义方法能节省内存?
每次用 new 创建对象时,如果方法写在构造函数里(比如 this.sayName = function() {...}),每个实例都会生成一个全新函数对象。而写在 prototype 上的方法,只在原型对象上存在一份,所有实例通过隐式原型链访问它,不重复创建函数。
如何正确把方法放到原型上?
推荐在构造函数外部统一设置 prototype 属性,避免逐个赋值导致覆盖默认 constructor:
- 用
Person.prototype.methodName = function() {...}单个添加 - 或一次性重写整个
prototype,但记得手动恢复constructor指向:
function Person(name) {
this.name = name;
}
Person.prototype = {
constructor: Person, // 关键:修复 constructor
sayName() {
console.log(this.name);
},
walk() {
console.log(this.name + ' is walking');
}
};
注意原型链与实例属性的优先级
当实例自身有同名属性/方法时,会屏蔽原型上的对应成员——这是正常行为,不影响共享逻辑:
- 实例上的
this.sayName会优先被调用,不再查找原型 - 若想强制调用原型方法,可用
Person.prototype.sayName.call(this) - 删除实例属性后,原型方法自动“浮现”,例如
delete person1.sayName
现代替代方案:类语法更清晰
ES6 的 class 本质仍是基于原型,但写法更直观、不易出错:
class Animal {
constructor(name) {
this.name = name;
}
speak() { // 自动挂到 Animal.prototype
console.log(this.name + ' makes a sound');
}
}
编译或运行时,speak 仍存在于 Animal.prototype,所有实例共享。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











