前端笔记(关于es5与es6实现继承的理解)

关于继承,我之前知道的事es6的继承,写法更偏向于java。但是es6的继承是一种语法糖,他的内部原理还是es5的原型链继承

首先要了解构造函数、原型、实例的关系。

 

图片来自网络

构造函数prototype指向原型

原型constructor指向构造函数

实例constructor指向构造函数

实例_proto_指向原型

 

我们先来看下es6的继承方式

//父类
class Person{
    constructor(name,age){
        this.name=name
        this.age=age
    }
    sayName(){
        console.log(this.name)
    }
    static A(){
        console.log("父类静态函数")
    }
}
//子类
class Child extends Person{
    constructor(sex,name,age){
        super(name,age)
        this.sex=sex
        this.x=2
        super.x=3//super指向子类this
        console.log(this.x)//3 改了x
        console.log(super.x)//undefined super代表父类 但父类没有x方法
    }
    static A(){
        console.log("子类静态函数")
        super.A()
    }
}
let c=new Child("男","张三",20)
console.log(c)
c.sayName()//子实例调用父类函数
Child.A()//调用静态函数

使用class声明,Child继承自Person,使用extends

super()要在子类的constructor中使用,代表父类的构造函数,返回this对象,指向子类。子类里必须写super(),用于将父类的属性方法传给子类。

super既可以是函数也可以是对象,但是不能直接打印。

super在子类中代表this,可以改变属性

constructor类的构造函数

继承后子类就可以调用父类的方法了,本身没有的,js会向对象的原型上面找

 

 

 

es5方式如何继承?

原型链实现继承:

子构造函数的原型对象=父构造函数的实例

//父类构造
const Person=function(name,age){
    this.name=name
    this.age=age
}
Person.prototype.sayName=function(){
    console.log(this.name)
}
//子类构造
const Child=function(sex,name,age){
    this.sex=sex
    this.name=name
    this.age=age
}
Child.prototype=new Person()
let c=new Child("男","张三",20)
console.log(c)
c.sayName()

上方代码可知,原本父类Person和子类Child的是并没有什么关系的,但是通过原型指向后,就形成了父子继承关系。

 

构造函数call改变指向形成继承:

//父类构造
const Person=function(name,age){
    this.name=name
    this.age=age
}
Person.prototype.sayName=function(){
    console.log(this.name)
}
//子类构造
const Child=function(sex,name,age){
    this.sex=sex
    Person.call(this,name,age)
}
let c=new Child("男","张三",20)
console.log(c)

call可以改变实例的指向,指向this就是指向子类

这种方式有个缺点:就是无法继承父类上原型链的函数,只能继承内部属性和内部方法。

所以,一般使用混合继承方式:

const Person=function(name,age){
    this.name=name
    this.age=age
}
Person.prototype.sayName=function(){
    console.log(this.name)
}
const Child=function(sex,name,age){
    this.sex=sex
    Person.call(this,name,age)
}
// Child.prototype=new Person()
Child.prototype=Object.create(Person.prototype)
Child.prototype.constructor=Child
let c1=new Child("男","张三",20)
console.log(c1)
c1.sayName()

让子类的原型构造器指向自己,形成原型链

 

posted @ 2020-04-30 16:51  herry菌  阅读(215)  评论(0编辑  收藏