ES5继承
ES5中没有class,所以es5的继承都是通过this指向改变和原型链去模拟继承。
• 构造函数式继承
• 原型式链式继承
• 组合式继承
1、首先有一个构造函数Animal如下。
function Animal(name,age){
this.name = name;
this.age = age;
}
Animal.prototype.run = function(name){
console.log(`${name}会跑!`)
}
2、有一个Cat构造函数想继承Animal,首先通过构造函数式继承去继承属性,代码如下。
function Cat(name,age,weight){
Animal.call(this,name,age); //关键代码。
this.weight = weight;
}
这里进行let cat = new Cat('橘猫‘,2,‘5kg’) ,console 出cat发现如图,属性name,age已经继承到了cat实例上了。
3、接下来进行方法继承。方法继承是通过原型链继承实现的。如下。
Cat.prototype = Animal.prototype;
此时在Cat的原型上添加方法,也会改变Animal的原型,显然不否和继承的特性。所以我们稍微改动一下写法。
Cat.prototype = new Animal()
我们将Animal构造函数的实例地址交给cat.这里在Cat原型上添加新方法就不会影响到Animal的原型了,因为Animal可以有无数个实例。
这里我们发现,run方法已经成功继承到了,但是proto上出现了两个无用属性,很难看,所以我们再改动一下写法。
var Fun = new Function()
Fun.prototype = Animal.prototype
Cat.prototype = new Fun()
先用一个干净的构造函数,将其prototype指向Animal的prototype,这样他俩原型一样,但是Fun上没有挂载name,age属性,所以继承下来会没有空属性。
3、组合式继承,将构造函数式继承和原型继承进行组合,就称为组合式继承。
组合式继承的缺点:组合式继承会两次调用基类的构造函数:第一次,子类的原型声明为基类的一个实例;第二次,子类的构造函数中调用基类的构造函数。
4、寄生组合式继承
Object.create(prototype,descpritor)是ES5 中定义的方法,返回值是生成对象,第一个参数是生成对象的原型,第二个是对象,用于定义属性或者方法
ps:原型对象_ proto_ : 构造函数的实例的_ proto_ 就是改构造函数的prototype
function extend(SuperClass, SubClass) {
SubClass.prototype = Object.create(SuperClass.prototype)
SubClass.prototype.constructor = SubClass;
}
//SubperClass 为父类,SubClass为子类。
es6继承
es6中出现了class和关键字super,extends
class Animal{
constructor(name, age){
this.name = name;
this.age = age;
}
run(){
console.log("我会跑")
}
}
class Cat extends Animal{
constructor(name,age,sex){
super(name,age)
this.sex = sex
}
}
var cat = new Cat('咪咪', 21, '母')
cat.run()
console.log(cat)