在面向对象编程中,继承是指一个类(称为子类或派生类)可以从另一个类(称为父类、基类或超类)继承属性和方法的机制。子类可以继承父类的属性和方法,并且可以添加新的属性和方法,也可以重写父类的方法以实现特定的行为。
通过继承,子类可以重用父类的代码,避免重复编写相似的代码。
通过将共同的属性和方法放在父类中,可以更好地组织和抽象代码,提高代码的可维护性和可扩展性。
通过继承,可以实现多态性,即通过父类的引用调用子类的方法,实现不同对象对同一消息的不同响应。
在JavaScript中,实现继承的方式有多种,以下是一些主要的继承方式:
原型链继承是基于原型的继承方式,它利用了JavaScript的原型特性来实现继承。在这种方式中,子类型的原型被设置为父类型的一个实例。
function Parent() {
this.parentProperty = true;
}
Parent.prototype.getParentProperty = function() {
return this.parentProperty;
};
function Child() {
this.childProperty = false;
}
// 继承自Parent
Child.prototype = new Parent();
var childInstance = new Child();
console.log(childInstance.getParentProperty()); // true
通过使用父类型的构造函数来增强子类型的实例,可以在子类型构造函数中调用父类型构造函数。
function Parent(name) {
this.name = name;
this.colors = ['red', 'blue', 'green'];
}
function Child(name) {
Parent.call(this, name); // 调用父类型构造函数
}
var childInstance = new Child('Child Name');
console.log(childInstance.name); // Child Name
组合继承结合了原型链继承和构造函数继承的优点,即通过原型链继承原型上的属性和方法,通过构造函数继承实例属性。
function Parent(name) {
this.name = name;
this.colors = ['red', 'blue', 'green'];
}
Parent.prototype.sayName = function() {
console.log(this.name);
};
function Child(name, age) {
Parent.call(this, name); // 借用构造函数继承属性
this.age = age;
}
Child.prototype = new Parent(); // 原型链继承方法
Child.prototype.constructor = Child;
var childInstance = new Child('Child Name', 5);
childInstance.sayName(); // Child Name
console.log(childInstance.age); // 5
原型式继承是基于已有对象创建新对象,使用Object.create()可以实现。
var parent = {
name: 'parent',
colors: ['red', 'blue', 'green']
};
var childInstance = Object.create(parent);
childInstance.name = 'child';
console.log(childInstance.colors); // ["red", "blue", "green"]
寄生式继承类似于原型式继承,但是可以在创建新对象时增加新的属性或方法。
function createAnother(original) {
var clone = Object.create(original);
clone.sayHi = function() {
console.log('Hi');
};
return clone;
}
var parent = {
name: 'parent',
colors: ['red', 'blue', 'green']
};
var childInstance = createAnother(parent);
childInstance.sayHi(); // Hi
寄生组合式继承是一种高效的继承方式,它通过借用构造函数来继承属性,而通过原型链的混成形式来继承方法。
function inheritPrototype(subType, superType) {
var prototype = Object.create(superType.prototype);
prototype.constructor = subType;
subType.prototype = prototype;
}
function Parent(name) {
this.name = name;
this.colors = ['red', 'blue', 'green'];
}
Parent.prototype.sayName = function() {
console.log(this.name);
};
function Child(name, age) {
Parent.call(this, name);
this.age = age;
}
inheritPrototype(Child, Parent);
Child.prototype.sayAge = function() {
console.log(this.age);
};
var childInstance = new Child('Child Name', 5);
childInstance.sayName(); // Child Name
childInstance.sayAge(); // 5
ES6 引入了基于类的语法,使得继承更加直观和易于理解。
class Parent {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name);
}
}
class Child extends Parent {
constructor(name, age) {
super(name); // 调用父类的constructor
this.age = age;
}
sayAge() {
console.log(this.age);
}
}
let childInstance = new Child('Child Name', 5);
childInstance.sayName(); // Child Name
childInstance.sayAge(); // 5
根据不同的需求和场景,开发者可以选择最适合的继承方式。
添加图片注释,不超过 140 字(可选)
关注公众号『前端也能这么有趣
』,获取更多有趣内容。
这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 ,平时也喜欢写些东西,既为自己记录 ,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 ,写错的地方望指出,定会认真改进 ,偶尔也会在自己的公众号『
前端也能这么有趣
』发一些比较有趣的文章,有兴趣的也可以关注下。在此谢谢大家的支持,我们下文再见 。