JS继承方式

       

目录

 原型链继承

 构造继承

 组合继承

寄生组合

 类继承(推荐使用):


       JS有好几种继承方式,但是每个继承方式都有各自的优缺点,接下来我给大家讲一下我所了解的继承方式。

 原型链继承

首先先看代码:

function  Person(){
            this.name='雪球',
            this.age=18,
            this.eat=['香蕉'],
            this.hobby={
                  watch:'电视剧',
                  sleep:'睡觉'
            }
        }
        // 原型链继承
        Person.prototype.setMethods=function (){
            console.log("我是person原型链上的一个方法");
        }
        function student(){}
        student.prototype=new Person()
        let  student1=new student()
        student1.name='小喵'
        student1.eat.push('葡萄')
        student1.hobby.watch='电影'
        console.log('student1');
        console.log( "name:"+student1.name+",eat:"+student1.eat+",hobby的watch:"+student1.hobby.watch);
        // console.log(student1);
        // ====================
        let  student2=new student()
        console.log('student2');
        console.log( "name:"+student2.name+",eat:"+student2.eat+",hobby的watch:"+student2.hobby.watch);

        // console.log(student2);

    在此代码中,让子类student构造函数的原型指向父类person构造函数,然后我改了student1的基本数据类型‘姓名’,属于对象类型的爱好里面的watch属性值,还为数组类型eat添加了‘葡萄’。

接下来我们看一下输出结果:

                                           

从结果可以看出修改student1的属性后,只有基本数据类型的值未被改变,其余值均受到了影响,我们输出一下student1和student2看看区别:

                                        

       从上图可以看出当采用原型链继承时,通过子类修改的基本数据那么他会直接在当前子类实例中添加一个这个基本数据类型并赋予新值。但是当我们通过子类修改引用型数据类型,他会直接进入原型中将数据进行修改,因此当我们访问新的子类实例时由于原型属性被修改,所以所查看到的引用数据类型是之前修改过的。

原型链继承总结:        

        父类的实例对象是子类的原型,优点:父类方法可以复用,缺点:1.父类所有引用类数据(对象,数组)会被子类共享,更改一个子类的数据,其他数据会受到影响,一直变化。2.子类实例不能给其他父类构造函数传参。

 构造继承

 function student(){
                Person.call(this)
        }

在子类student构造函数中将person的指向更改之后放入进去,这时我们和之前一样修改属性,展示结果如下:

                      

发现student2并没有随着student1中属性值的改变而改变,但是它有一个缺点就是:无法访问父类原型链上的属性和方法。

举例说明:         

                                               

结果:             

  会发现无法访问父类原型链上的方法。

构造函数的继承总结:
优点:父类的引|用类型的数据不会被子类共享不会互相影响
缺点:子类不能访问父类原型属性上的方法和参数

 组合继承

组合继承结合了原型链和构造继承两个方法:即:

 // 组合继承
        function student(){
                Person.call(this)
        }
        student.prototype=new Person()

结果:不但可以访问到父类原型链中的方法,而且更改一个子类的数据,其他数据没有受到影响。

一切都看似很完美,解决了原型链和构造继承的问题,但是它也有一个缺点:

它其实相当于将person的方法复制了一份到子类student,然后原型链还存在了一份,这会造成性能降低。

组合继承总结:

优点:1.父类可以复用   2.父类构造函数中的引用属性数据不会被共享
缺点: 会调用两次父类的构造函数,会有两份一样的属性和方法,会影响性能。

寄生组合

    // 寄生继承
        function student(){
                Person.call(this)
        }
         function Fn(){}
        Fn.prototype=Person.prototype
        student.prototype= new Fn()

结果:不存在两份一样的属性和方法。

寄生组合总结:

通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免的组合继承的缺点。

 类继承(推荐使用):

一段代码就可以实现:

  class student extends Person{}

结果:上述问题也均未出现

我所熟悉的继承的几种方法到这里就结束啦,如果大家还有新的补充可以在评论区留言哦。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值