在 ES5 中,实现继承通常有以下几种方法:
1. 原型链继承
这是最常用的继承方式,通过设置一个构造函数的原型为另一个构造函数的实例来实现。
javascript
function Parent() {
this.name = 'Parent';
}
Parent.prototype.say = function() {
console.log('Hello from parent');
};
function Child() {
Parent.call(this); // 继承Parent构造函数的属性
this.name = 'Child';
}
Child.prototype = new Parent(); // 继承Parent原型
Child.prototype.constructor = Child; // 修正构造函数指向
var childInstance = new Child();
console.log(childInstance.name); // 输出 "Child"
childInstance.say(); // 输出 "Hello from parent"
2. 构造函数继承
直接在子构造函数中调用父构造函数。
javascript
function Parent(name) {
this.name = name;
}
Parent.prototype.say = function() {
console.log('Hello from parent');
};
function Child(name) {
Parent.call(this, name); // 继承Parent构造函数的属性
this.name = name;
}
var childInstance = new Child('Child');
console.log(childInstance.name); // 输出 "Child"
childInstance.say(); // 输出 "Hello from parent"
3. 组合继承(推荐)
结合原型链继承和构造函数继承的优点。
javascript
function Parent(name) {
this.name = name;
this.colors = ['red', 'blue', 'green'];
}
Parent.prototype.say = function() {
console.log('Hello from parent');
};
function Child(name, age) {
Parent.call(this, name); // 继承Parent构造函数的属性
this.age = age;
}
Child.prototype = new Parent(); // 继承Parent原型
Child.prototype.constructor = Child; // 修正构造函数指向
Child.prototype.sayAge = function() {
console.log('Age: ' + this.age);
};
var childInstance = new Child('Child', 10);
console.log(childInstance.name); // 输出 "Child"
childInstance.say(); // 输出 "Hello from parent"
childInstance.sayAge(); // 输出 "Age: 10"
4. 寄生式继承
创建一个空函数作为父类型,将子类型的方法添加到这个空函数的原型上。
javascript
function Parent(name) {
this.name = name;
}
Parent.prototype.say = function() {
console.log('Hello from parent');
};
function inheritPrototype(Child, Parent) {
var prototype = Object.create(Parent.prototype);
prototype.constructor = Child;
Child.prototype = prototype;
}
function Child(name, age) {
Parent.call(this, name);
this.age = age;
}
inheritPrototype(Child, Parent);
Child.prototype.sayAge = function() {
console.log('Age: ' + this.age);
};
var childInstance = new Child('Child', 10);
console.log(childInstance.name); // 输出 "Child"
childInstance.say(); // 输出 "Hello from parent"
childInstance.sayAge(); // 输出 "Age: 10"
这些方法各有优缺点,组合继承是ES5中最常用的继承方式,因为它结合了原型链继承和构造函数继承的优点,既能继承属性,又能继承方法。