javascript 通过原型链实现方法复用,核心做法是将函数挂载到构造函数的 prototype 属性上。这样所有实例对象都能共享同一个函数引用,从而节省内存并避免重复定义。当调用实例方法时,引擎会沿着原型链向上查找,直到找到对应的函数执行。

构造函数与原型对象的关联机制是什么
每个 JavaScript 函数在创建时都会自动获得一个 prototype 属性,该属性指向一个默认的空对象,即原型对象。当使用 new 关键字调用构造函数时,新创建的实例对象内部会有一个隐藏链接(现代 JS 中通常称为 [[Prototype]])指向构造函数的 prototype。这种关联使得实例可以直接访问原型上的属性和方法。如果我们在原型对象上定义一个方法,所有通过该构造函数创建的实例都将共享这个方法,而不是为每个实例单独创建一份副本。

function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log('Hello, ' + this.name);
};
const p1 = new Person('Alice');
const p2 = new Person('Bob');
p1.greet(); // Hello, Alice
p2.greet(); // Hello, Bob
console.log(p1.greet === p2.greet); // true
上述代码展示了标准的原型方法复用模式。Person 是构造函数,greet 方法被添加到 Person.prototype 上。创建 p1 和 p2 两个实例后,它们都可以通过点语法访问 greet 方法。关键验证点在于 p1.greet === p2.greet 返回 true,证明两个实例引用的是内存中的同一个函数对象,而非各自独立的副本。这直接体现了方法复用的内存优势。
修改原型对象对已存在实例有什么影响
由于实例是通过引用链接到原型对象的,因此在实例创建之后修改原型对象,这些更改会立即反映在所有现有实例上。这是因为原型对象是一个共享的容器,任何对它的读写操作都会影响所有指向它的实例。这种动态特性允许我们在运行时扩展或修补类的功能,而不需要重新创建已有的实例对象。需要注意的是,如果在实例上定义了与原型同名的属性或方法,实例自身的属性会屏蔽原型上的同名成员,这种现象称为属性遮蔽。

function Animal(type) {
this.type = type;
}
Animal.prototype.speak = function() {
return '...';
};
const dog = new Animal('Dog');
console.log(dog.speak()); // ...
// 在实例创建后修改原型
Animal.prototype.speak = function() {
return this.type + ' says woof!';
};
console.log(dog.speak()); // Dog says woof!
// 演示属性遮蔽
const cat = new Animal('Cat');
cat.speak = function() {
return 'Meow';
};
console.log(cat.speak()); // Meow
console.log(Animal.prototype.speak.call(cat)); // Cat says woof!
这段代码首先创建了 dog 实例,此时它继承自原型的默认 speak 方法。接着我们直接替换了 Animal.prototype.speak,再次调用 dog.speak() 时,输出变成了新的内容,证实了原型修改对已存在实例的即时影响。随后创建 cat 实例并为其自身添加了 speak 方法,此时 cat.speak() 输出 'Meow',因为实例自身的属性优先级高于原型属性。最后通过 call 强制绑定上下文调用原型方法,输出了原型当前的定义,进一步验证了原型链的查找机制和遮蔽现象的存在。
为什么推荐使用 Object.create 替代 new 进行原型继承
虽然 new 关键字结合构造函数是实现原型复用的经典方式,但 Object.create 提供了更纯粹的原型链创建机制,不强制要求构造函数执行。在某些场景下,我们可能只需要一个基于特定原型的对象,而不想触发构造函数内部的初始化逻辑(如设置默认属性或执行副作用)。使用 Object.create 可以直接指定原型对象,生成的实例与原型之间的链接关系与 new 创建的实例完全一致,同样支持方法复用,但语义上更清晰地表达了“基于原型创建对象”的意图,避免了构造函数带来的隐式行为干扰。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











