JavaScript原型链继承本质是通过__proto__或Object.setPrototypeOf()让对象指向另一对象以复用属性方法,核心是构造函数prototype被实例隐式原型引用;需用Parent.call(this)继承实例属性,Object.create(Parent.prototype)继承原型方法并修复constructor;ES6 class是其语法糖,底层仍为原型链。

JavaScript 中的原型链继承,本质是让一个对象的 __proto__(或通过 Object.setPrototypeOf())指向另一个对象,从而复用其属性和方法。核心在于构造函数的 prototype 对象被实例的隐式原型所引用。
构造函数 + prototype + new 实现基础继承
这是最经典、最贴近“类继承”语义的方式:
- 定义父构造函数,并在其
prototype上添加共享方法; - 定义子构造函数,在内部用
Parent.call(this, ...)借用父类构造逻辑(实现属性继承); - 将子构造函数的
prototype设置为父构造函数的一个实例(Object.create(Parent.prototype)),建立原型链; - 手动修复子构造函数的
constructor指向(否则会指向父构造函数)。
示例:
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name} makes a sound`);
};
function Dog(name, breed) {
Animal.call(this, name); // 继承实例属性
this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype); // 继承原型方法
Dog.prototype.constructor = Dog; // 修复 constructor
Dog.prototype.bark = function() {
console.log(`${this.name} barks!`);
};
const dog = new Dog("Leo", "Golden Retriever");
dog.speak(); // Leo makes a sound(来自 Animal.prototype)
dog.bark(); // Leo barks!(自身方法)
ES6 class 语法糖:更简洁的原型链继承
class 和 extends 是对上述模式的封装,底层仍是原型链:
立即学习“Java免费学习笔记(深入)”;
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
-
extends Parent自动设置子类prototype的原型为Parent.prototype; -
super()在子类构造器中调用父类构造函数,等价于Parent.call(this, ...); - 静态方法、getter/setter、
super.xxx调用都基于原型查找规则。
等效写法:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // 相当于 Animal.call(this, name)
this.breed = breed;
}
bark() {
console.log(`${this.name} barks!`);
}
}
注意原型链继承的关键细节
避免常见陷阱,才能真正理解机制:
-
属性 vs 方法继承不同步:实例属性只能靠
Parent.call(this)或super()复制;方法靠原型链动态查找; -
共享引用属性的风险:若父类
prototype上有数组或对象,所有子实例共用同一份(如Animal.prototype.friends = []),修改会影响全部; -
instanceof 依赖原型链:判断依据是对象的整个
__proto__链是否包含某构造函数的prototype; -
不推荐直接改
__proto__:它是非标准、性能差的旧方式,应优先使用Object.setPrototypeOf()或Object.create()。
现代替代方案:组合优于继承
原型链继承适合行为复用,但面对复杂对象关系时易产生紧耦合。实践中常结合以下方式:
-
对象展开(浅拷贝):
{...parent, ...child}快速合并数据; - 函数复用(mixin):把方法对象 assign 到目标原型上,实现多行为组合;
-
代理与委托:用
Proxy拦截访问,将某些操作委托给其他对象。
这些不是取代原型链,而是根据场景选择更清晰、可控的复用策略。

















