美文网首页JavaScript 使用记录
JavaScript 继承 6 寄生组合式继承

JavaScript 继承 6 寄生组合式继承

作者: 赵者也 | 来源:发表于2017-12-18 09:36 被阅读33次

前面介绍的组合继承最大的问题就是无论什么情况下,都会调用两次父类型的构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数内部。没错,子类型最终会包含父类型对象的全部实例属性,但我们不得不在调用子类型构造函数时重写这些属性:

        function SuperColors(colorName) {
            if (typeof colorName != "undefined") {
                this.colors = ["red", "green", "blue", colorName];
            } else {
                this.colors = ["red", "green", "blue"];
            }
        }
        SuperColors.prototype.sayColors = function () {
            console.log(this.colors);
        };
        function SubColors(colorName, level) {
            // 继承属性
            SuperColors.call(this, colorName); // 第2次调用 SuperColors

            this.level = level;
        }

        SubColors.prototype = new SuperColors(); // 第1ss次调用 SuperColors

        SubColors.prototype.sayLevel = function () {
            console.log(this.level);
        };

解决这个问题的办法是使用寄生组合式继承。所谓寄生组合式继承,即通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。

其思路是:不必为了指定子类型的原型而调用父类型的构造函数,我们所需要的无非就是父类型原型的一个副本而已。本质上,就是使用寄生式继承来继承父类型的原型,然后再将结果指定给子类型的原型。

寄生组合式继承的基本模式如下:

        function inheritPrototype(subType, superType) {
            var prototype = Object.create(superType.prototype); // 创建对象
            prototype.constructor = subType;  // 增强对象
            subType.prototype = prototype; // 指定对象
        }

这个实例中 inheritPrototype 函数实现了寄生组合式继承的最简单形式:

  1. 创建父类型原型的一个副本;
  2. 为创建的副本添加 constructor 属性,从而弥补因重写原型而失去的默认的 constructor 属性;
  3. 将新创建的对象(即副本)赋值给子类型的原型。

这样,我们就可以调用 inheritPrototype 函数来修改前面的组合继承的例子了:

function SuperColors(colorName) {
            if (typeof colorName != "undefined") {
                this.colors = ["red", "green", "blue", colorName];
            } else {
                this.colors = ["red", "green", "blue"];
            }
        }
        SuperColors.prototype.sayColors = function () {
            console.log(this.colors);
        };
        function SubColors(colorName, level) {
            // 继承属性
            SuperColors.call(this, colorName);

            this.level = level;
        }

        inheritPrototype(SubColors, SuperColors);

        SubColors.prototype.sayLevel = function () {
            console.log(this.level);
        };

        var instance1 = new SubColors("gray", 0);
        instance1.colors.push("white");
        instance1.sayColors();
        instance1.sayLevel();

        var instance2 = new SubColors("black", 1);
        instance2.sayColors();
        instance2.sayLevel();

输出结果:

输出结果

这个例子的高效率体现在它只调用了一次 SuperColors 构造函数,并且因此避免了在 SubColors.prototype 上面创建不必要的、多余的属性。与此同时,原型链还能保持不变;因此,还能够正常使用 instanceof 和 isPrototypeOf。开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式。

相关文章

  • javaScript 实现继承方式

    JavaScript实现继承共6种方式:原型链继承、借用构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合式继承。

  • Javascript 继承

    参考:JavaScript高级程序设计(第3版) 原型链 原型式继承 寄生式继承 寄生组合式继承

  • JS类的继承

    1.类式继承 构造函数继承 3.组合继承 4.原型继承 5.寄生式继承 6.寄生组合式继承

  • 18-深入拓展原型链模式(六种常用继承方式)

    1. 原型继承 2. call继承 3. 冒充对象继承 4.组合式继承 5. 寄生组合式继承 6. 中间类继承

  • js继承方式

    类式继承 构造函数继承 组合继承 类式继承 + 构造函数继承 原型式继承 寄生式继承 寄生组合式继承 寄生式继承 ...

  • (九)

    寄生组合式继承前面说过,组合继承是JavaScript最常用的继承模式;不过,它也有自己的不足。组合继承最大的问题...

  • JavaScript 继承 6 寄生组合式继承

    前面介绍的组合继承最大的问题就是无论什么情况下,都会调用两次父类型的构造函数:一次是在创建子类型原型的时候,另一次...

  • 前端面试题总结【38】:javascript继承的 6 种方法

    原型链继承 借用构造函数继承 组合继承(原型+借用构造) 原型式继承 寄生式继承 寄生组合式继承 推荐: 持续更新...

  • JavaScript继承

    1.原型链 2.借用构造函数 3.组合继承 4.原型式继承 5.寄生式继承 6.寄生组合式继承 未续待完...

  • js的完美继承方式详解

    分为六步,能看完的话,不会你打我 类式继承、构造函数继承、组合继承、原型继承、寄生式继承、寄生组合式继承 困了 安

网友评论

    本文标题:JavaScript 继承 6 寄生组合式继承

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