一、组合继承
组合继承,有时候也叫作伪经典继承,指的是将原型链和借用构造函数的技术组合到一块,从而发挥二者之长的一种继承模式。其背后的思路是使用原型链实现对原型和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又能保证每个实例都要它自己的属性。
//父类
function SuperType(name,color){
this.name = name;
this.color = "red";
}
SuperType.prototype.sayName = function(){
console.log(this.name);
}
//子类
function SubType(name,age){
//继承属性
SuperType.call(name,age);
this.age = age;
}
//继承方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
console.log(this.age);
}
在这个例子中, SuperType 构造函数定义了两个属性: name 和 colors 。
SuperType 的原型定义了一个方法 sayName() 。 SubType 构造函数在调用 SuperType 构造函数时传入了 name 参数,紧接着又定义了它自己的属性 age 。然后,将 SuperType 的实例赋值给 SubType 的原型,然后又在该新原型
上定义了方法 sayAge() 。这样一来,就可以让两个不同的 SubType 实例既分别拥有自己属性——包
括 colors 属性,又可以使用相同的方法了。
继承属性
这里继承父类的属性,调用父类的构造函数,函数只不过是在特定环境中执行代码的对象,因此通过使用apply()和call()方法可以在新创建的对象上执行构造函数,如图。
继承方法
这里继承方法,直接将父类SuperType的实例赋值给SubType的原型,
第一行SubType.protorype = new SuperType();它相当于删除了prototype原先的值,然后赋予了一个新值
第二行SubType.prototype.constructor = SubType;原来,任何一个prototype对象都有一个constructor属性,指向它的构造函数。如下图所示。
由于第一行的SubType.protorype = new SuperType();使得SubType.prototype.constructor=SuperType,所以需要第二行的SubType.prototype.constructor = SubType;把它改过来。
组合继承避免了原型链和借用构造函数的缺陷,融合了它们的优点,成为 JavaScript 中最常用的继
承模式。而且, instanceof 和 isPrototypeOf() 也能够用于识别基于组合继承创建的对象。
二、ES6的继承
/* 基类 */
class Person{
constructor(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
};
sayHello(){
console.log("hello world")
};
sayName(){
console.log("My name is"+this.name);
}
}
/* 子类 */
class Student extends Person{
constructor(name,age,sex,score){
super(name,age,sex);
this.score = score;
}
}
let student = new Student("zx",18,"male",99);
console.log(student.name); //zx
student.sayHello(); //hello world
student.sayName(); //My name is zx
在es6中,声明类直接用class,类的属性都写在构造函数constructor里面,类的方法不再需要写在prototype对象里面了,可以直接写在类中,并且子类可以调用父类的该方法。
子类继承父类只需要一个extends关键字即可,子类的构造函数里面想要继承父类的构造函数只需要使用super关键字即可。