构造函数--继承详解

作者: bo_bo_bo_la | 来源:发表于2017-12-22 21:44 被阅读18次

先写一个父级的构造函数

        function Parent(name){
            this.name = name;
            this.money = 10000000;
            this.hobby = function(){
                console.log("Parent this.hobby");
            }
        }
        Parent.prototype.active = function(){
            console.log("Parent.prototype");
        }
        Parent.prototype.eat = function(){
            console.log("Parent.prototype.eat");
        }

接着子集的构造方法

        function Son(name){
        }

子集想要继承父级里面的内容就要在里面加上

        function Son(name){
            Parent.call(this,name);
        }

这样就可以继承父级里面的内容

        var newSon = new Son("rrrr");
        console.log(newSon.name);  // rrrr
        console.log(newSon.money); // 10000000
        newSon.hobby(); // Parent this.hobby

这样写看似没什么问题,但是当我们在子集里面写上与父级相同的属性或者方法呢?

        function Son(name){
            Parent.call(this,name);  // rrrr
            this.money = 10; 
            this.hobby = function(){
                console.log("Son this.hobby");
            }
        }
        var newSon = new Son("rrrr");
        console.log(newSon.name);  // rrrr
        console.log(newSon.money); // 10
        newSon.hobby(); // Son this.hobby

上述代码表明,子集继承父级,在自身重写该方法的时候以自身为准
回到上述继承 构造继承

              function Parent(name){
            //属性
            this.name = name;
            this.money = 10000000
            //实例方法
            this.hobby = function(){
                console.log("Parent this.hobby");
            }
        }
        //原型方法
        Parent.prototype.active = function(){
            console.log("Parent.prototype");
        }
        Parent.prototype.eat = function(){
            console.log("Parent.prototype.eat");
        }
        function Son(name){
            Parent.call(this,name);
        }
        var newSon = new Son("rrrr");
        console.log(newSon.name);  // rrrr
        console.log(newSon.money);  // 100000
        console.log(newSon instanceof Parent); // false
        console.log(newSon instanceof Son); // true
        newSon.hobby()  //  Parent this.hobby
        newSon.active();  // 报错
        newSon.eat();  // 报错

由上述可知,子集继承父级,只继承父级本身的属性和方法,不会继承父级原型上的方法,因为构造继承的核心就是使用父类的构造函数来增强子类的实例,等于是复制父类的实例属性给子类(没用到原型)
特点:

  • 解决子类实例共享父类引用属性的问题
  • 创建子类实例时,可以向父类传参数
  • 可以实现多继承,(call多个父类对象)
    缺点:
  • 实例并不是父类的实例,只是子类的实例
  • 只能继承父类的实例属性和方法,不能继承原型属性和方法
  • 无法实现函数复用,每个子类都有父类实力函数的副本,影响性能

这就可以利用到 实例继承

        function Son(name){
            var ins = new Parent(name);
            return ins;
        }
        var newSon = new Son("ggg");
        console.log(newSon.name);   // ggg
        console.log(newSon.money);   // 10000000
        console.log(newSon instanceof Parent);   // true
        console.log(newSon instanceof Son);   // false
        newSon.hobby()  //  Parent this.hobby
        newSon.active();  //  Parent.prototype
        newSon.eat(); //  Parent.prototype.eat

实例继承的核心。为父类实例添加新特性,作为子类实例返回
特点:

  • 不限制调用方式,不管是 new 子类() 还是 子类() ,返回的对象具有相同的效果
    缺点:
  • 实例是父级的实例,不是子类的实例
  • 不支持多继承

再有 组合继承

        function Son(name){
            Parent.call(this,name);
        }
        
        Son.prototype.eat = function(){
            console.log("Son.prototype.eat");
        }
        Son.prototype = new Parent();
        var newSon = new Son("ggg");
        console.log(newSon.name);   // ggg
        console.log(newSon.money);   // 10000000
        console.log(newSon instanceof Parent);   // true
        console.log(newSon instanceof Son);   // true
        newSon.hobby()  //  Parent this.hobby
        newSon.active();  //  Parent.prototype
        newSon.eat(); //  Parent.prototype.eat

组合继承的核心是通过父类构造,继承父类的属性并保留传参的优点,然后通过降幅及实例子类原型,实现函数复用
特点:

  • 可以继承实例属性、方法,也可以继承原型属性、方法
  • 即是子类的实例,也是父类的实例
  • 不存在引用属性共享问题
  • 可传参
  • 函数可复用
    缺点:
  • 调用了两次父类构造函数,生成两份实例(父类实例将子类原型上的那份屏蔽了),

最后寄生组合继承,通过创建一个空的构造函数。

        function Son(name){
            Parent.call(this,name);
        }
        
        Son.prototype.eat = function(){
            console.log("Son.prototype.eat");
        }
        //创建一个空的构造函数
        function Link(){}
        //将Person4 里面的构造函数的原型 传址赋值 到 Link构造函数的原型里面
        Link.prototype = Parent.prototype;
        //实例化Student的构造方法的原型。此时  实例化的时候会重新创建一个新的地址存储,所以改变
        //Student里面的方法的时候 不会影响Link  当然 也不会影响Person4
        Son.prototype = new Link();
        var newSon = new Son("tt")
        console.log(newSon.name);   // tt
        console.log(newSon.money);   // 10000000
        console.log(newSon instanceof Parent);   // true
        console.log(newSon instanceof Son);   // true
        newSon.hobby()  //  Parent this.hobby
        newSon.active();  //  Parent.prototype
        newSon.eat(); //  Parent.prototype.eat

相关文章

  • 构造函数--继承详解

    先写一个父级的构造函数 接着子集的构造方法 子集想要继承父级里面的内容就要在里面加上 这样就可以继承父级里面的内容...

  • Javascript如何实现继承

    构造函数继承 原型构造函数组合继承

  • 继承中执行顺序讨论

    继承中,子父类的构造函数(构造函数不被继承)1.子类必须调用父类的构造函数(构造函数不被继承)(1)如果没有写调用...

  • JavaScript的六种继承方式

    JavaScript的几种继承方式 原型链继承 借助构造函数继承(经典继承) 组合继承:原型链 + 借用构造函数(...

  • 继承方法

    构造函数/原型/实例的关系 借助构造函数实现继承 借助原型链实现继承(弥补构造函数实现继承不足) 组合方式(组合原...

  • JavaScript的构造函数扩展、继承以及封装

    构造函数的扩展 扩展Man构造函数 构造函数的继承 Dog 继承 Pig JavaScript 内置对象的扩展 例...

  • js基础之实现继承的几种方式

    js 实现继承的方式有: 原型链继承; 构造函数继承; 组合继承(原型链继承 + 构造函数继承)(最常用);(原型...

  • ES5 和 ES6 继承比较:

    ES5构造函数和继承: ES6构造函数和继承:

  • 继承

    传统继承(原型链) 过多的继承了没用的属性 借用构造函数 不能继承借用构造函数的原型每次构造函数都要多走一个函数 ...

  • js继承

    1、原型式继承:借助构造函数的原型对象实现继承,即 子构造函数.prototype = 父构造函数.prototy...

网友评论

    本文标题:构造函数--继承详解

    本文链接:https://www.haomeiwen.com/subject/atixgxtx.html