`
IT男男
  • 浏览: 14655 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

JavaScript寄生组合式继承

    博客分类:
  • js
 
阅读更多

组合继承是javaScript最常用的继承模式;不过,它也有自己的不足。组合继承最大的问题就是无论什么情况下,都会调用两次超类型构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数内部。没错,子类型最终会包含超类型对象的全部实例属性,但我们不得不在调用子类型构造函数时重写这些属性。再来看一看下面组合继承的例子。

function SuperType(name) {
    this.name = name;
    this.colors = ["red", "blue", "green"];
}

SuperType.prototype.sayName = function () {
    alert(this.name);
};

function SubType(name, age){
    SuperType.call(this, name);       //第二次调用SuperType()
    this.age = age;
}

SubType.prototype = new SuperType();  //第一次调用SuperType()
SubType.prototype.construcotr = SubType;
SubType.prototype.sayAge = function() {
    alert(this.age);
}

var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors);  //"red,blue,green,black"
instance1.sayName();      //"Nicholas"
instance1.sayAge();       //29

var instance2 = new SubType("Greg", 27);
alert(instance2.colors);  //"red,blue,green"
instance2.sayName();      //"Greg"
instance2.sayAge();       //27

加粗字体的行中是调用SuperType构造函数的代码。在第一次调用SuperType构造函数时,SubType.prototype会得到两个属性:name和colors;它们都是SuperType的实例属性,只不过现在位于SubType的原型中。当调用SubType构造函数时,又会调用一次SuperType构造函数,这一次又在新对象上创建了实例属性name和colors。于是,这两个属性就屏蔽了原型中的两个同名属性。

所谓寄生式组合继承,即通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。其背后的基本思路是:不必为了指定子类型的原型而调用超类型的构造函数,我们所需要的无非就是超类型原型的一个副本而已。本质上,使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。寄生组合式继承的基本模式如下所示。

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

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

这个示例中的inheritPrototype()函数实现了寄生组合式继承的最简单形式。这个函数接收两个参数:子类型构造函数和超类型构造函数。在函数内部,第一步是创建超类型原型的一个副本。第二步是为创建的副本添加constructor属性,从而弥补因重写原型而失去的默认的constructor属性。最后一步,将新创建的对象赋值给子类型的原型。这样,我们就可以使用inheritPrototype()函数的语句,去替换前面例子中为子类型原型赋值的语句了,例如:

function SuperType(name) {
    this.name = name;
    this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function() {
    alert(this.name);
};

function SubType(name, age) {
    SuperType.call(this, name);
    this.age = age;
}

inheritPrototype(SubType, SuperType);

SubType.prototype.sayAge = function() {
    alert(this.age);
}

var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors);  //"red,blue,green,black"
instance1.sayName();      //"Nicholas"
instance1.sayAge();       //29

var instance2 = new SubType("Greg", 27);
alert(instance2.colors);  //"red,blue,green"
instance2.sayName();      //"Greg"
instance2.sayAge();       //27

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

分享到:
评论

相关推荐

    JavaScript寄生组合式继承实例详解

    本文实例讲述了JavaScript寄生组合式继承。分享给大家供大家参考,具体如下: 其实《JavaScript高级程序设计》这本书中已经有完整代码了,只要把代码读懂就知道这个继承是怎么回事。 首先,在js中,给对象定义属性有...

    JavaScript寄生组合式继承原理与用法分析

    本文实例讲述了JavaScript寄生组合式继承。分享给大家供大家参考,具体如下: 寄生组合式继承 寄生组合式继承,就是通过伪造对象来继承属性,通过原型链的混成形式来继承方法。 这种技术的基本思路是:不必为了指...

    【JavaScript源代码】简单谈谈JavaScript寄生式组合继承.docx

    简单谈谈JavaScript寄生式组合继承  组合继承也被称为伪经典继承,它综合了我们昨天说的原型链和盗用构造函数,将俩者的有点结合在了一起。它的基本思想是使用原型链继承原型上的属性和方法,通过盗用构造函数继承...

    JavaScript继承基础讲解(原型链、借用构造函数、混合模式、原型式继承、寄生式继承、寄生组合式继承)

    主要介绍了JavaScript继承基础讲解,原型链、借用构造函数、混合模式、原型式继承、寄生式继承、寄生组合式继承,需要的朋友可以参考下

    【JavaScript源代码】深入JS继承.docx

     目录 前言准备总结继承的n种方式原型式继承原型链式继承借用构造函数(类式继承)组合继承寄生组合式继承结束语 前言 准备 总结 继承的n种方式 原型式继承原型链式继承借用构造函数(类式继承)组合继承寄生组合...

    [js高手之路]寄生组合式继承的优势详解

    在之前javascript面向对象系列的文章里面,我们已经探讨了组合继承和寄生继承,回顾下组合继承: function Person( uName ){ this.skills = [ 'php', 'javascript' ]; this.userName = uName; } Person....

    js实现的七种继承方式.md

    使用js实现继承的七种方式,详细讲解了js中的原型链继承,构造函数继承,组合继承(经典继承),原型式继承,寄生式继承,寄生组合式继承,以及ES6中的继承,描述原理以及实现和要点概述等。

    对于JS继承详细介绍( 原型链,构造函数,组合,原型式,寄生式,寄生组合,Class extends)

    说实在话,以前我只需要知道“寄生组合继承”是最好的,有个祖传代码...其中,原型链继承和原型式继承有一样的优缺点,构造函数继承与寄生式继承也相互对应。寄生组合继承基于Object.create, 同时优化了组合继承,成

    深入理解javascript原型链和继承

    主要介绍了javascript原型链和继承的概念,以及使用原型链实现继承、经典继承、组合式继承、寄生组合式继承。非常实用,是篇非常不错的文章,这里推荐给大家。

    javascript 中的继承实例详解

    寄生组合式继承 后记 继承有两种方式:接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际的方法。 由于函数没有签名,在ECMAScript中无法实现接口继承。ECMAScript只支持实现继承,而且实现继承...

    javascript-learning:Javascript开发人员之路

    类式继承(class)组合式继承(combination)构造函数式继承(constructor)多继承(multi)寄生式继承(parasitic)寄生组合式继承(parasitic-combination)原型式继承(prototype)> data-structure <js数据结构> design-...

    wenfujie#document-library#原型以及原型链1

    使用构造函数创建对象原型小结原型链js中继承的几种方法原型链继承借用构造函数继承组合继承原型式继承寄生式继承(常用)寄生组合式继承使用构造函数创建对象var p

    史上最为详细的javascript继承(推荐)

    寄生组合 原型链继承 相信小伙伴们都知道到原型链继承(ECMAScript 中描述了原型链的概念,并将原型链作为实现继承的主要方法),因为原型链继承非常的强大,但是也有它的缺点,接下来咱们就按照上面的维度看看原型...

    javascript继承的六大模式小结

    本文给大家详细总结了下javascript继承的六大模式,分别为1.原型链,2.借用构造函数,3.组合继承,4.原型式继承,5.寄生式继承,6.寄生组合式继承,十分的全面,有需要的小伙伴可以参考下。

    《javascript设计模式》学习笔记二:Javascript面向对象程序设计继承用法分析

    本文实例讲述了Javascript面向对象程序设计继承用法。分享给大家供大家参考,具体...原型赋值(遍历)继承(寄生式继承) 2.构造函数继承 所谓的构造函数继承,就是通过创建一个新对象,调用父类构造函数实现的一种继承

Global site tag (gtag.js) - Google Analytics