组合继承(Combination Inheritance)是 JavaScript 中一种常用的继承模式,它结合了原型链继承和构造函数继承的优点。通过组合继承,我们可以使用构造函数继承来继承实例属性,并通过原型链继承来继承共享的方法和属性。
原理
组合继承的原理是结合使用构造函数和原型链。通过构造函数来继承实例属性和方法,通过原型链来继承共享的属性和方法。
具体步骤如下:
- 定义一个父类(基类),它包含一些共享的属性和方法。我们可以使用构造函数来定义这些属性和方法。
- 定义一个子类(派生类),它继承了父类的属性和方法。我们可以使用构造函数继承来继承父类的实例属性和方法。
- 将子类的原型设置为一个新创建的父类的实例。这样子类就能够通过原型链继承父类的共享属性和方法。
这种组合继承的方法能够实现子类既能够继承父类的实例属性和方法,又能够继承父类的共享属性和方法。它是 JavaScript 中常用的一种继承方式。
实现方法
下面是组合继承的实现方法:
代码语言:javascript复制// 父类
function Parent(name) {
this.name = name;
this.colors = ['red', 'blue', 'green'];
}
Parent.prototype.sayName = function() {
console.log('My name is ' 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() {
console.log('I am ' this.age ' years old');
};
// 创建子类实例
var child1 = new Child('Alice', 10);
child1.sayName(); // 输出:My name is Alice
child1.sayAge(); // 输出:I am 10 years old
// 修改子类实例的属性
child1.colors.push('yellow');
console.log(child1.colors); // 输出:['red', 'blue', 'green', 'yellow']
// 创建另一个子类实例
var child2 = new Child('Bob', 8);
child2.sayName(); // 输出:My name is Bob
child2.sayAge(); // 输出:I am 8 years old
// 验证另一个子类实例的属性不受影响
console.log(child2.colors); // 输出:['red', 'blue', 'green']
在上面的示例代码中,我们定义了一个父类 Parent
// 父类
function Parent(name) {
this.name = name;
this.colors = ['red', 'blue', 'green'];
}
Parent.prototype.sayName = function() {
console.log('My name is ' this.name);
};
首先,我们定义了一个父类 Parent
,它接收一个参数 name
并将其赋值给实例属性 this.name
。父类还有一个共享的属性 colors
,它是一个包含颜色字符串的数组。父类还定义了一个共享方法 sayName()
,用于打印实例的名字。
// 子类
function Child(name, age) {
// 继承父类的实例属性和方法
Parent.call(this, name);
this.age = age;
}
接下来,我们定义了一个子类 Child
,它接收两个参数 name
和 age
。在子类的构造函数中,我们使用 Parent.call(this, name)
来继承父类的实例属性和方法。这里的 call()
方法可以将父类的构造函数在子类的上下文中执行,从而使子类的实例具有父类的属性和方法。我们还定义了子类自己的实例属性 this.age
。
// 继承父类的共享属性和方法
Child.prototype = new Parent();
Child.prototype.constructor = Child;
Child.prototype.sayAge = function() {
console.log('I am ' this.age ' years old');
};
接下来,我们将子类的原型设置为一个新创建的父类的实例 Child.prototype = new Parent()
。这样子类就可以通过原型链继承父类的共享属性和方法。我们还将子类原型的构造函数指向子类自身,以确保正确的构造函数指向。
在子类中,我们定义了子类自己的方法 sayAge()
,用于打印子类实例的年龄。
最后,我们创建了两个子类实例 child1
和 child2
,并分别调用了父类和子类的方法来验证继承关系。我们还修改了 child1
实例的属性 colors
,并验证了另一个子类实例 child2
的属性不受影响。