js——继承

原型继承

1)核心: 将父类实例作为子类原型
2)优点: 方法复用
3)缺点:
1、创建子类实例的时候,不能传参
2、子类实例共享了父类的构造函数的引用属性,比如foods
3、无法实现多继承

		//父类
        function School(name,foods){
            this.name=name
            this.foods=['甜品']
            this.person=function(){
                console.log(this.name+'吃'+this.foods);
            }
        }
        //父类原型对象添加方法
        School.prototype.print=function(){
            console.log(this.name,this.foods);
        }
        //子类
        function Student(){}
        //原型继承
        Student.prototype=new School()
        //纠正constructor指向
        Student.prototype.constructor=Student
        //创建实例
        let stu1=new Student()
        let stu2=new Student()
        stu1.name='jack'
        stu1.foods.push('罐头')
        console.log(stu1.name);
        console.log(stu1.foods);
        stu1.person()
        stu1.print()
        console.log('——————————————————————————————————————————————');
        stu2.name='rose'
        stu2.foods.push('香蕉')
        console.log(stu2.name);
        console.log(stu2.foods);
        stu2.person()  
        stu2.print()  

构造函数继承

1)核心: 借用父类的构造函数来增强子类实例,等于复制父类的实例属性给子类
2)优点: 实例之间独立
1、创建子类实例,可以向父类构造函数传参数。
2、子类实例不共享父类的构造函数的引用属性。如foods属性
3、可实现多继承(通过多个call或者apply继承多个父类)
3)缺点
1、父类的方法不能复用
由于方法再父构造函数中定义,导致方法不能复用(因为每次创建子类实例都要创建一遍方法)
2、子类实例,继承不了父类原型上的属性(因为没有用到原型)

		function School(name,foods){
            this.name=name
            this.foods=['甜品']
            this.person=function(){
                console.log(this.name+'吃'+this.foods);
            }
        }
        School.prototype.print=function(){
            console.log(this.name,this.foods);
        }
        function Student(name,money){
            School.call(this,name)
            this.money=money
        }
        let stu1=new Student('jack',20000)
        let stu2=new Student('rose',20000)
        
        stu1.foods.push('苹果')
        stu1.person()
        console.log(stu1.name)
        console.log(stu1.money)
        console.log(stu1.foods);

        console.log('——————————————————————————————————————');

        stu2.foods.push('梨子')
        stu2.person()
        console.log(stu2.name)
        console.log(stu2.money)
        console.log(stu2.foods);
        console.log(stu2.print);//undefined

组合继承

1)核心: 通过调用父类构造函数,继承父类的属性和方法并保留传参的优点;然后通过将父类实例作为子类原型,实现函数的复用
2)优点
1、保留构造函数的优点:创建子类实例,可以向父类构造函数传参
2、保留原型链优点:父类的方法定义在父类的原型对象上,可以实现方法复用
3、不共享父类的引用属性,比如foods属性
3)缺点:
1、由于调用了2次父类的构造方法,会存在一份多余的父类实例对象。Student.prototype的父类属性和方法会被School.call(this)拷贝来的实例属性屏蔽掉
2、注意组合继承方式,要记得修复Student.prototype.constructor的指向

        function School(name,foods){
            this.name=name
            this.foods=['甜品']
            this.person=function(){
                console.log(this.name+'吃'+this.foods);
            }
        }
        School.prototype.print=function(){
            console.log(this.name,this.foods);
        }
        function Student(name,money){
            School.call(this,name)
            this.money=money
        }
        Student.prototype = new School()
        Student.prototype.constructor = Student
        let stu1=new Student('jack',20000)
        let stu2=new Student('rose',20000)
        
        stu1.foods.push('苹果')
        stu1.person()
        console.log(stu1.name)
        console.log(stu1.money)
        console.log(stu1.foods);

        console.log('——————————————————————————————————————');

        stu2.foods.push('梨子')
        stu2.person()
        console.log(stu2.name)
        console.log(stu2.money)
        console.log(stu2.foods);
        stu2.print()

组合继承优化1

1)核心: 通过这种方式,砍掉父类的实例属性,这样在调用父类的构造函数的时候,就不会初始化两次实例,避免组合继承的缺点。
2)优点:
1、只调用一次父类的构造函数
2、保留构造函数的优点:创建子类实例,可以向父类构造函数传参
3、保留原型链的优点:父类的实例方法定义在父类的原型对象上,可以实现方法复用
3)缺点:
1、修正构造函数的指向后,父类实例的构造函数指向,同时也发生变化

		function School(name,foods){
            this.name=name
            this.foods=['甜品']
            this.person=function(){
                console.log(this.name+'吃'+this.foods);
            }
        }
        School.prototype.print=function(){
            console.log(this.name,this.foods);
        }
        function Student(name,money){
            School.call(this,name)
            this.money=money
        }
        Student.prototype = School.prototype
        Student.prototype.constructor=Student
        let stu1=new Student('jack',20000)
        let stu2=new Student('rose',20000)
        
        stu1.foods.push('苹果')
        stu1.person()
        console.log(stu1.name)
        console.log(stu1.money)
        console.log(stu1.foods);

        console.log('——————————————————————————————————————');

        stu2.foods.push('梨子')
        stu2.person()
        console.log(stu2.name)
        console.log(stu2.money)
        console.log(stu2.foods);
        stu2.print()

组合继承优化2(寄生式组合继承)

完美!!!!

        function School(name,foods){
            this.name=name
            this.foods=['甜品']
            this.person=function(){
                console.log(this.name+'吃'+this.foods);
            }
        }
        School.prototype.print=function(){
            console.log(this.name,this.foods);
        }
        function Student(name,money){
            School.call(this,name)
            this.money=money
        }
        Student.prototype = Object.create(School.prototype)
        Student.prototype.constructor = Student

        let stu1=new Student('jack',20000)
        let stu2=new Student('rose',20000)
        
        stu1.foods.push('苹果')
        stu1.person()
        console.log(stu1.name)
        console.log(stu1.money)
        console.log(stu1.foods);

        console.log('——————————————————————————————————————');

        stu2.foods.push('梨子')
        stu2.person()
        console.log(stu2.name)
        console.log(stu2.money)
        console.log(stu2.foods);
        stu2.print()

类继承

super :调用父类中的构造函数(constructor)

        class Father {
            constructor(x,y){
                this.x=x
                this.y=y
            }
            sum(){
                console.log(this.x+this.y);
            }
        }
        class Son extends Father{
            constructor(x,y){
                super(x,y)
            }
        }
        var son = new Son(1,2)
        son.sum()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值