JavaScript继承原理
ES6继承(语法糖)
关键字:extends和super
-
extends
- 表达继承关系,书写在要声明的类后面,后面是要继承的父类。
- extends需与super搭配使用,如果写了构造函数,里面必须调用super(),否则会保存;如果没不写构造,JS会自动为我们写一个空的构造器,并自动调super();
-
super
- super() 方法放在子类的构造函数中,只能调用一次,且必须放在this和return之前(最好写在构造函数第一行)。如果父类需要传参,小括号内为传入的实参。
class Student extends Person{
constructor(){
super();//可传参,实参
this.xxx=xxx;
......
}
}
继承原理(ES5)
- 混合继承=方法借用(继承属性)+原型继承(将父类的原型插入子类的原型链)
- 方法借用
- call
- apply
- bind
- 原型继承
- Object.create()
- 方法借用
function Super(name, age) {//父类,超类
this.name = name;
this.age = age;
}
Object.assign(Super.prototype, {
sleep() {
console.log(`${this.name} is sleeping!`);
}
})
//子类
function Sub(name, age, gender) {
Super.call(this, name, age);
//以调用父类构造函数的形式,得到执行结果,将this绑定为当前的实例对象
//普通调用时,this的指向window而不是当前实例对象,所以使用方法借用,绑定this的指向
this.gender = gender;
}
//原型继承(插入父类的原型链,如果父类在子类的原型链上,那么子类及其实例对象都可以通过原型链找到父类身上方法)
// 父类原型插入的位置,实例对象和子类之间不可,因为实例对象必须指向创建它的类的原型对象;Obj原型和null之间不可,规定Obj.prototype指向null.只能在子类原型和Obj原型之间插入
。
Sub.prototype = Object.create(Super.prototype);//以父类的prototype为原型,创建一个空对象,替换子类的prototype
Sub.prototype.constructor = Sub;//由于空对象身上没有constructor引用,赋值
//自己的方法
Object.assign(Sub.prototype, {
eat() {
console.log(`${this.name} is eating!`);
}
});
let sub1 = new Sub("zs", 18, "male");
// sub1.constructor===>fn Sub//sub1通过自己身上的__proto__指向创建它的类的原型对象 //Sub.prototype,prototype身上有它所在的构造函数的引用constructor
//sub1.__proto__.constructor====>fn Sub
```