Js是如何实现继承的?

目录

1.原型链继承

2.构造函数继承

3.组合式继承

4.ES6中的Class类继承


1.原型链继承

        让一个构造函数的原型是另一个类型的实例,那么这个构造函数new出来的实例具有该实例的属性。

function Parent(){
    this.Show = true
    this.info = {
        name:'abc',
        age:18
    }
}

//在它的原型上添加一个方法
Parent.prototype.getInfo = function(){
    console.log(this.Show)
    console.log(this.info)
}

function Child(){
    
}

//子类的原型等于父类的实例
Child.prototype = new Parent()

let Child1 = new Child()
Child1.info.gender = '男'
Child1.getInfo()    //{name:'abc' , age:18 , gender:'男'} true

        优点:写法便捷,容易理解。

        缺点:对象实例共享所有继承的属性和方法,无法向父类构造函数传参。

2.构造函数继承

        在子类型构造函数的内部调用父类型构造函数,使用apply()或call()方法将父对象的构造函数绑定在子对象上。

function Parent(gender){
    this.info = {
        name:'abc',
        age:18,
        gender:gender
    }
}

function Child(gender){
    Parent.call(this,gender)
}

let Child1 = new Child('男')
console.log(Child1.info)      //{name:'abc' , age:18 , gender:'男'} 

        优点:解决了原型链实现继承不能传参的问题和父类的原型共享问题。

        缺点:方法都在构造函数中定义,无法实现函数复用。在父类的原型中定义的方法,对子类而言是不可见的,所有的类型都只能使用构造函数模式。

3.组合式继承

        将原型链和构造函数这两种继承方法组合到一起,使用原型链对原型属性和方法进行继

承;使用构造函数对实例属性进行继承,结合了二者的特点。

function Person(gender){
    console.log('我执行了')
    this.info = {
        name:'abc',
        age:18,
        gender:gender
    }
}

//使用了原型链继承原型上的属性和方法
Person.prototype.getInfo = function(){
    console.log(this.info.name,this.info.age)   //abc 18
}

function Child(gender){
    //使用了构造函数传递参数
    Person.call(this,gender)
}

Child.prototype = new Person()

let Child1 = new Child('男')
Child1.getInfo()
console.log(Child1.info)    //{name:'abc',age:18,gender:'男'}

        优点:结合了二者的特点。

        缺点:无论什么情况下都会调用两次父类构造函数。一次是在创建子类原型的时候,另一次是在子类构造函数的内部。

4.ES6中的Class类继承

        Class通过extends关键字实现继承,原理是先创造出父类的this对象,然后使用子类的构造函数修改this。

        子类的构造方法中必须调用super方法,只有在调用super()之后才能使用this,因为子类的this对象是继承父类的this对象,然后对其进行加工,而super方法表示的是父类的构造函数,用来创建父类的this对象。

class Animal{
    constructor(kind){
        this.kind = kind
    }
    getKind(){
        return this.kind
    }
}

//继承
class Cat extends Animal{
    constructor(name){
        //子类的构造方法中必须先调用super方法
        super('cat')
        this.name = name
    }    
    getCatInfo(){
        console.log(this.name + ':' + super.getKind())
    }
}

const cat1 = new Cat('biu')
cat1.getCatInfo()   //biu:cat

        优点:语法简单,操作方便。

        缺点:浏览器兼容性差,并不是所有浏览器都支持class关键字。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值