JavaScript原型动态扩展有两种方式:一是向构造函数prototype添加属性/方法,使所有实例共享;二是用Object.setPrototypeOf()修改单个对象的原型。前者推荐用于统一扩展,后者适用于临时增强特定实例,应避免使用非标准的__proto__。

JavaScript 中原型对象动态添加新功能,核心是往 构造函数的 prototype 上挂属性或方法,或用 Object.setPrototypeOf() 直接替换已有对象的原型。两种路径适用不同场景,关键在“谁共享”和“何时生效”。
给构造函数原型加功能(所有实例共享)
这是最常用、最推荐的方式,适合为一类对象统一扩展行为。
- 语法简单:直接赋值到
Constructor.prototype.xxx = function() {...} - 新增方法/属性会自动被所有已存在和未来创建的实例继承
- 适用于自定义构造函数、类(
class的静态prototype)甚至内置对象(如String.prototype.trim)
示例:
function Animal(name) {
this.name = name;
}
// 动态添加共享方法
Animal.prototype.speak = function() {
return `${this.name} makes a sound`;
};
const dog = new Animal('Dog');
const cat = new Animal('Cat');
console.log(dog.speak()); // "Dog makes a sound"
console.log(cat.speak()); // "Cat makes a sound"
给已有对象实例改原型(单个对象临时增强)
当只需要某个具体对象拥有新能力,又不想影响其他同类实例时,用 Object.setPrototypeOf()。
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 目标明确:只改一个对象的
[[Prototype]] - 新原型可以是普通对象、另一个构造函数的
prototype,甚至null - 不能用于
Object.freeze()、Object.seal()或不可扩展对象
示例:
const base = { id: 1 };
const obj = { title: 'Report' };
Object.setPrototypeOf(obj, base);
console.log(obj.id); // 1 ← 从 base 原型继承
console.log(obj.title); // 'Report' ← 自身属性
避免用 __proto__ 直接赋值
虽然 obj.__proto__ = newProto 看似等效,但它属于非标准遗留属性:
- 语义不清晰,可读性差
- 部分严格环境或旧引擎可能不支持
- ES 规范明确推荐使用
Object.setPrototypeOf()替代
不推荐写法:
// ❌ 不规范,不推荐 obj.__proto__ = Animal.prototype; // ✅ 标准、安全、语义明确 Object.setPrototypeOf(obj, Animal.prototype);
补充:运行时修改原型链本身也有效
原型对象本身也是普通对象,可随时增删改它的属性——这些变更会立刻反映到所有继承它的实例上。
- 添加:
Animal.prototype.run = function() {...} - 修改:
Animal.prototype.speak = function() { ... } - 删除:
delete Animal.prototype.speak
注意:删除后,已存在的实例调用该方法会报 TypeError,因为查找失败且原型链已断。

















