- 原型链继承(Prototype Inheritance) :
// 父类
function Animal(name) {
this.name = name;
}
// 父类方法
Animal.prototype.sayName = function() {
console.log('My name is ' + this.name);
};
// 子类
function Dog(name, breed) {
Animal.call(this, name);
this.breed = breed;
}
// 子类继承父类
Dog.prototype = new Animal();
// 创建实例
var myDog = new Dog('Buddy', 'Labrador');
myDog.sayName(); // 输出:My name is Buddy
优点:
- 简单易懂,原型链清晰。
- 父类的属性和方法可以被子类共享。
缺点:
- 所有子类实例共享同一个父类实例,可能导致子类实例之间的属性共享问题。
- 无法在不影响所有子类实例的情况下向父类构造函数传递参数。
- 构造函数继承(Constructor Inheritance) :
// 父类
function Animal(name) {
this.name = name;
}
// 父类方法
Animal.prototype.sayName = function() {
console.log('My name is ' + this.name);
};
// 子类
function Dog(name, breed) {
Animal.call(this, name); // 调用父类构造函数
this.breed = breed;
}
// 创建实例
var myDog = new Dog('Buddy', 'Labrador');
myDog.sayName(); // 错误:myDog.sayName is not a function
优点:
- 可以向父类构造函数传递参数,使得子类实例可以拥有独立的属性。
缺点:
- 无法继承父类原型上的方法。
- 每个子类实例都有自己的一份父类属性的副本,可能造成内存浪费。
- 组合继承(Combination Inheritance) :
// 父类
function Animal(name) {
this.name = name;
}
// 父类方法
Animal.prototype.sayName = function() {
console.log('My name is ' + this.name);
};
// 子类
function Dog(name, breed) {
Animal.call(this, name); // 调用父类构造函数
this.breed = breed;
}
// 子类继承父类
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
// 创建实例
var myDog = new Dog('Buddy', 'Labrador');
myDog.sayName(); // 输出:My name is Buddy
优点:
- 既继承了父类的属性,又继承了父类原型上的方法。
- 可以向父类构造函数传递参数,使得子类实例可以拥有独立的属性。
缺点:
- 调用两次父类构造函数,可能会影响性能。
- 原型式继承(Prototype-based Inheritance) :
// 原型对象
var animal = {
sayName: function() {
console.log('My name is ' + this.name);
}
};
// 创建新对象并继承原型
var dog = Object.create(animal);
dog.name = 'Buddy';
// 调用方法
dog.sayName(); // 输出:My name is Buddy
优点:
- 简单快捷,无需定义构造函数。
- 可以轻松地创建多个对象,并且可以选择性地修改继承的属性。
缺点:
- 无法实现私有成员和方法。
- 所有对象共享同一个原型对象,可能导致意外的修改和副作用。
- ES6中的类继承:
// 父类
class Animal {
constructor(name) {
this.name = name;
}
sayName() {
console.log('My name is ' + this.name);
}
}
// 子类
class Dog extends Animal {
constructor(name, breed) {
super(name); // 调用父类构造函数
this.breed = breed;
}
}
// 创建实例
let myDog = new Dog('Buddy', 'Labrador');
myDog.sayName(); // 输出:My name is Buddy
优点:
- 语法简洁清晰,易于理解和维护。
- 可以继承父类的属性和方法,并且可以调用父类构造函数。
缺点:
- 不支持私有属性和方法。
- 对于一些旧版本的JavaScript引擎可能不完全支持。
这些继承方式各有优缺点,具体使用时需要根据实际情况选择合适的方式。常见的优点包括代码复用、灵活性和可维护性,而缺点主要涉及性能、内存占用和代码复杂度等方面。