原型对象是构造函数的prototype属性指向的共享对象,所有实例通过[[prototype]]链继承其方法,内存中仅存一份;若在构造函数内用this定义方法则每次new都会重复创建,浪费资源。

JavaScript 中原型对象通过构造函数的 prototype 属性来存储共享的方法和变量。它本质上是一个普通对象,所有由该构造函数创建的实例,都会隐式关联到这个原型对象,并从中继承属性和方法——不是复制,而是共享引用。
原型对象是共享的“公共仓库”
每个函数(包括构造函数)一创建,就自动拥有一个 prototype 属性,指向一个空对象(即原型对象)。这个对象默认带有一个 constructor 属性,指回原构造函数。关键在于:所有实例共用同一个 prototype 对象,因此往里面加的方法或属性,自然被所有实例访问和使用。
- 定义在
prototype上的方法,在内存中只存在一份 - 实例调用时,JS 引擎通过内部
[[Prototype]]链(即__proto__)向上查找到它 - 例如:
person1.sayHi === person2.sayHi返回 true,说明是同一个函数引用
为什么不能直接在构造函数里定义方法?
如果在构造函数体内用 this.method = function(){...} 定义方法,每次 new 实例时都会新建一份函数对象,占用额外内存:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
p1.greet和p2.greet是两个不同函数,p1.greet === p2.greet为 false - 对 1000 个实例来说,就是 1000 份重复代码,浪费资源
- 而原型方式只需一份,所有实例按需查找使用
哪些内容适合放在 prototype 上?
遵循“不变、通用、复用”的原则:
- 所有实例行为一致的方法:如
toString()、sayHi()、calculateAge() - 所有实例默认相同的只读属性(谨慎):如
User.prototype.type = 'member' - 避免放可变引用类型(如数组、对象),否则多个实例会意外共享同一份数据
实际写法示例
标准做法是分两层设计:
- 构造函数内初始化 实例专属数据:
this.name、this.id -
Constructor.prototype上挂载 共享方法:Constructor.prototype.getName
function Animal(name, species) {
this.name = name; // 每个实例独有
this.species = species; // 每个实例独有
}
Animal.prototype.speak = function() { // 所有实例共享
return `${this.name} says hello!`;
};
const a1 = new Animal('Lily', 'cat');
const a2 = new Animal('Max', 'dog');
console.log(a1.speak === a2.speak); // trueJava免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










