看了这篇,代码如下:
let cc = (...val) => console.log(...val);
function inheritPrototype(sub, sup) {
var clone = Object.create(sup.prototype);
clone.constructor = sub;
sub.prototype = clone;
}
function SuperType(name) {
this.name = name;
this.friends = ['gay1', 'gay2'];
// cc('SuperType Constructor');
}
SuperType.prototype.sayName = function() {
cc(this.name);
};
function SubType(name, age) {
SuperType.call(this, name); // 组合继承-第1次调用父类构造函数
this.age = age;
}
// 寄生组合继承
inheritPrototype(SubType, SuperType);
// 组合继承(会调用父类的2次构造函数)
// SubType.prototype = new SuperType(); // 组合继承-第1次调用父类构造函数
SubType.prototype.sayAge = function() {
cc(this.age);
}
// test
var me = new SubType('zmy', 21);
var she = new SubType('mqy', 18);
me.friends.push('gay3');
me.sayName();
me.sayAge();
cc(me.friends);
cc(she.friends);
cc(me instanceof SubType);
cc(me instanceof SuperType);
cc(SubType.prototype.isPrototypeOf(me));
cc(SuperType.prototype.isPrototypeOf(me));
// zmy
// 21
// [ 'gay1', 'gay2', 'gay3' ]
// [ 'gay1', 'gay2' ]
// true
// true
// true
// true
也可以看看继承的多种方式和优缺点,讲了好几个继承的优缺点。
总结一下 继承的多种方式和优缺点:
原型链继承主要是这句:
Child.prototype = new Parent();
缺点:
- 父类引用类型的属性被所有实例共享
- 在创建 Child 的实例时,不能向Parent传参
借用构造函数(经典继承) 主要是这句:
Parent.call(this);
优点:
- 避免了引用类型的属性被所有实例共享
- 可以在 Child 中向 Parent 传参
缺点:
- 方法都在构造函数中定义,每次创建实例都会创建一遍方法。
组合继承原型链继承和经典继承双剑合璧,以上2句都包括
优点:
- 融合原型链继承和构造函数的优点,是 JavaScript 中最常用的继承模式。
缺点:
- 会调用两次父构造函数。
寄生组合式继承没有用child.prototype = new Parent(),而是用inheritPrototype()继承:
function inheritPrototype(sub, sup) {
var clone = Object.create(sup.prototype);
clone.constructor = sub;
sub.prototype = clone;
}
优点:
它只调用了一次 Parent 构造函数,并且因此避免了在 Parent.prototype 上面创建不必要的、多余的属性。与此同时,原型链还能保持不变;因此,还能够正常使用 instanceof 和 isPrototypeOf。开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式。