JavaScript的继承机制是基于原型的,这为代码复用提供了多种模式。从早期的原型链继承到现代的ES6类语法,每种方式都有其适用场景和理解成本。了解这些模式对于设计和构建可扩展的应用程序结构至关重要。
![图片[1]-JavaScript继承的方式有哪些?-速码派](http://www.sumapai.com/wp-content/uploads/2026/01/6bef93977a494346aac3fe893c8baab4tplv-tb4s082cfz-aigc_resize_1080_1080-1024x683.webp)
原型链继承
这是最基本的继承方式,通过将子类的原型设置为父类的实例来实现。子类实例可以访问父类原型上定义的方法和属性。
function Parent() {
this.name = 'Parent';
}
Parent.prototype.sayName = function() {
return this.name;
};
function Child() {}
Child.prototype = new Parent();
const instance = new Child();
console.log(instance.sayName());
这种方式存在明显问题:所有子类实例共享同一个父类实例的引用属性。修改一个实例的引用属性(如数组)会影响到所有其他实例。
构造函数继承
为了解决原型链继承中引用属性共享的问题,可以在子类构造函数内部调用父类构造函数,从而为每个子类实例创建独立的属性副本。
function Parent(name) {
this.name = name;
this.colors = ['red'];
}
function Child(name) {
Parent.call(this, name);
}
const c1 = new Child('c1');
c1.colors.push('blue');
const c2 = new Child('c2');
console.log(c2.colors); // ['red']
这种方法虽然解决了属性独立的问题,但父类原型上定义的方法无法被子类实例访问到。
组合继承
组合继承结合了原型链和构造函数的优点,是最常用的经典继承模式。它使用构造函数继承属性,使用原型链继承方法。
function Parent(name) {
this.name = name;
}
Parent.prototype.sayName = function() {
return this.name;
};
function Child(name, age) {
Parent.call(this, name);
this.age = age;
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
Child.prototype.sayAge = function() {
return this.age;
};
这种方式既保证了实例属性的独立性,又能让方法被复用。缺点是父类构造函数被调用了两次,可能会存在一些效率问题。
寄生组合式继承
这是一种更高效的继承方式,被视为引用类型最理想的继承范式。它通过一个空函数作为中介来继承父类的原型,避免了不必要的父类构造函数调用。
function inherit(Child, Parent) {
const F = function() {};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
}
function Parent(name) {
this.name = name;
}
Parent.prototype.sayName = function() {
return this.name;
};
function Child(name, age) {
Parent.call(this, name);
this.age = age;
}
inherit(Child, Parent);
ES6的Object.create()方法让这种实现变得更简洁。
ES6的class继承
ES6引入了基于类的语法,它本质上是上述原型继承的语法糖,但写法更清晰、更接近传统面向对象语言。
class Parent {
constructor(name) {
this.name = name;
}
sayName() {
return this.name;
}
}
class Child extends Parent {
constructor(name, age) {
super(name);
this.age = age;
}
sayAge() {
return this.age;
}
}
extends关键字用于继承,super用于调用父类构造函数。这是现代JavaScript项目中最推荐使用的继承方式,它内部的工作原理依然是寄生组合式继承。
在实践中,对于新项目应优先使用ES6的class语法,它的意图明确且语法简洁。理解其背后的原型机制,有助于你更深入地调试和理解代码的行为。






















暂无评论内容