参考《JavaScript高级程序设计》(第四版)8.3 继承
原型链继承
缺点
- 原型包含引用类型时,所有实例会共享,造成修改混乱
- 创建子类不能向超类传参
function SuperType() {
this.name = 'super';
this.colors = ['red']
}
SuperType.prototype.sayName = function() {
console.log(this.name);
}
function SubType(age) {
this.age = age;
}
SubType.prototype = new SuperType();
const s1 = new SubType(10);
s1.colors.push('yellow')
console.log(s1);
s1.sayName();
运行结果
盗用构造函数继承
优点
- 解决了原型链继承不能传参的问题。
缺点
- 超类原型上的方法,子类不能使用
- 函数不能复用,因为必须在构造函数内部定义方法。
function SuperType(name) {
this.name = name;
this.colors = ['red'];
this.sayHi = function() {
console.log('HI');
}
}
SuperType.prototype.sayName = function() {
console.log(this.name);
}
function SubType(age, name) {
SuperType.call(this, name)
this.age = age;
}
const s1 = new SubType(10, 'Tom');
console.log(s1);
运行结果
组合继承
优点
- 解决了上述2种方式单独使用造成的问题
缺点
- 因为调用了2次超类构造函数,所有造成子类原型拥有很多不需要的属性。
function SuperType(name) {
this.name = name;
this.colors = ['red'];
}
SuperType.prototype.sayName = function() {
console.log(this.name);
}
function SubType(age, name) {
SuperType.call(this, name)
this.age = age;
}
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
const s1 = new SubType(10, 'Tom');
console.log(s1);
运行结果
原型式继承
用途:主要是为了实现对一个对象的简单继承,不是为了实现创造一个新的类型。
缺点
- 引用类型的问题。
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
let person = {
name: 'Lisa',
friends: ['Ann']
}
let anotherPerson = object(person);
anotherPerson.name = 'Tom';
anotherPerson.friends.push('Rob');
let anotherPerson2 = object(person);
anotherPerson2.name = 'Lily';
anotherPerson2.friends.push('Bob');
console.log(anotherPerson,anotherPerson2)
运行结果
寄生式继承
优点:可以实现对一个简单的对象继承,然后做扩展。
缺点:不能复用。
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
function createAnother(original) {
let clone = object(original);
clone.sayHi = function() {
console.log('Hi');
}
return clone;
}
let person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
let anotherPerson = createAnother(person);
anotherPerson.sayHi(); // "hi"
console.log(anotherPerson)
运行结果
寄生式组合继承
优点:解决组合继承会给子类原型添加不必要属性的问题。
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
function inheritPrototype(subType, superType) {
let prototype = object(superType.prototype);
subType.prototype = prototype;
subType.prototype.constructor = subType;
}
function SuperType(name) {
this.name = name;
this.colors = ['red'];
}
SuperType.prototype.sayName = function() {
console.log(this.name);
}
function SubType(age, name) {
SuperType.call(this, name)
this.age = age;
}
inheritPrototype(SubType, SuperType);
const s1 = new SubType(10, 'Tom');
console.log(s1);
运行结果