继承方式
- 原型链继承
function Parent() {
this.name = 'Parent';
}
Parent.prototype.sayName = function () {
console.log('My name is ' + this.name);
};
function Child() {}
Child.prototype = new Parent();
var child1 = new Child();
child1.sayName(); // My name is Parent
- 构造函数继承
function Parent(name) {
this.name = name;
}
function Child(name) {
Parent.call(this, name);
}
var child1 = new Child('Child');
console.log(child1.name); // Child
- 组合继承
function Parent(name) {
this.name = name;
}
Parent.prototype.sayName = function () {
console.log('My name is ' + this.name);
};
function Child(name) {
Parent.call(this, name);
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
var child1 = new Child('Child');
child1.sayName(); // My name is Child
- 原型式继承
function createObj(obj) {
function F() {}
F.prototype = obj;
return new F();
}
var parent = {
name: 'Parent',
sayName: function () {
console.log('My name is ' + this.name);
}
};
var child1 = createObj(parent);
child1.name = 'Child';
child1.sayName(); // My name is Child
- 寄生式继承
function createObj(obj) {
var clone = Object.create(obj);
clone.sayName = function () {
console.log('My name is ' + this.name);
};
return clone;
}
var parent = {
name: 'Parent'
};
var child1 = createObj(parent);
child1.name = 'Child';
child1.sayName(); // My name is Child
- 寄生组合式继承
function Parent(name) {
this.name = name;
}
Parent.prototype.sayName = function () {
console.log('My name is ' + this.name);
};
function Child(name) {
Parent.call(this, name);
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
var child1 = new Child('Child');
child1.sayName(); // My name is Child
优缺点
这些继承方式有各自的优缺点和应用场景:
- 原型链继承 优点:简单易懂,易于实现。 缺点:父类中引用类型的属性会被所有子类共享,在子类中修改该属性会影响所有子类。 应用场景:适用于单一对象的继承。
- 构造函数继承 优点:可以避免父类中引用类型的属性被所有子类共享的问题。 缺点:无法继承父类原型上的属性和方法,每个子类都会有一个父类的副本。 应用场景:适用于多个相似对象的继承。
- 组合继承 优点:结合了原型链继承和构造函数继承的优点,既能够继承父类原型上的属性和方法,又能够避免父类中引用类型的属性被所有子类共享的问题。 缺点:调用了两次父类构造函数,导致父类的实例属性和子类的实例属性重复。 应用场景:通用的继承方式,适用于大多数情况。
- 原型式继承 优点:简单方便,可以在不必创建自定义类型的情况下实现继承。 缺点:与原型链继承一样,父类中引用类型的属性会被所有子类共享,在子类中修改该属性会影响所有子类。 应用场景:适合在一个对象基础上创建新对象,或者在不想创建构造函数的情况下实现继承。
- 寄生式继承 优点:可以在不必创建自定义类型的情况下实现继承,并且可以向已有对象添加方法和属性。 缺点:同样存在与原型链继承相同的问题,即父类中引用类型的属性会被所有子类共享,在子类中修改该属性会影响所有子类。 应用场景:适合在一个对象基础上创建新对象,并且需要封装继承过程的情况。
- 寄生组合式继承 优点:避免了组合继承中调用两次父类构造函数的问题,既能够继承父类原型上的属性和方法,又能够避免父类中引用类型的属性被所有子类共享的问题。 缺点:略显繁琐,需要对父类原型进行一次浅拷贝。 应用场景:通用的继承方式,是组合继承的一种优化方案。