面向对象编程 -- 继承2
一、盗用构造函数
// 为了解决原型包含引用值导致的继承问题,一种叫作 “盗用构造函数” 的技术在开发社区流行起来。
// 基本思路很简单:在子类构造函数中调用父类构造函数。
function SuperType(){
this.colors = ["red", "blue", "green"];
}
function SubType(){
// 继承 SuperType
SuperType.call(this);
}
let instance1 = new SubType();
instance1.colors.push("black");
console.log(instance1.colors);
let instance2 = new SubType();
console.log(instance2.colors);

1.传递参数
// 相比于原型链,盗用构造函数的一个优点就是可以在子类构造函数中向父类构造函数传参。
function SuperType(name){
this.name =name;
}
function SubType(){
// 继承 SuperType 并传参
SuperType.call(this, "Nicholas");
// 实例属性
this.age = 29;
}
let instance = new SubType();
console.log(instance.name);
console.log(instance.age);

2.盗用构造函数的问题
// 盗用构造函数的主要缺点,也是使用构造函数模式自定义类型的问题:必须在构造函数中定义方法,因此函数不能重用。
二、组合继承
// 组合继承综合了原型链和盗用构造函数,将两者的优点集中了起来。
// 基本的思路是使用原型链继承原型上的属性和方法,而通过盗用构造函数继承实例属性。
function SuperType(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function() {
console.log(this.name);
};
function SubType(name, age){
// 继承属性
SuperType.call(this, name);
this.age = age;
}
// 继承方法
SubType.prototype = new SuperType();
SubType.prototype.sayAge = function() {
console.log(this.age);
};
let instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
console.log(instance1.colors); // "red,blue,green,black"
instance1.sayName(); // "Nicholas";
instance1.sayAge(); // 29
let instance2 = new SubType("Greg", 27);
console.log(instance2.colors); // "red,blue,green"
instance2.sayName(); // "Greg";
instance2.sayAge(); // 27
