1. 组合继承:又叫伪经典继承,是指将原型链和借用构造函数技术组合在一块的一种继承方式。

下面来看一个例子:

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;
} //继承方法
SubType.prototype = new 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(); // var instance2 = new SubType("Greg", 27);
alert(instance2.colors); //red,blue,green
instance2.sayName(); //Greg
instance2.sayAge(); //

组合继承避免了原型链和借用构造函数的缺陷,融合它们的优点。

2. 原型式继承

可以在不必预先定义构造函数的情况下实现继承,其本质是执行对给定对象的浅复制。而复制得到的副本还可以得到进一步的改造。

function object(o) {
function F(){};
F.prototype = o;
return new F;
} var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
}; var antherPerson = object(person);
antherPerson.name = "Greg";
antherPerson.friends.push("Rob"); var antherPerson = object(person);
antherPerson.name = "Linda";
antherPerson.friends.push("Barbie"); alert(person.friends); //Shelby,Court,Van,Rob,Barbie
 

3. 寄生式继承

与原型式继承非常相似,也是基于某个对象或某些信息创建一个对象,然后增强对象,最后返回对象。为了解决组合继承模式由于多次调用超类型构造函数而导致的低效率问题,可以将这个模式与组合继承一起使用。

function object(o) {
function F(){};
F.prototype = o;
return new F;
}
function createAnother(original) {
var clone = object(original);
clone.sayHi = function() {
alert("Hi");
};
return clone;
} var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
}; var anotherPerson = createAnother(person);
anotherPerson.sayHi();

4. 寄生组合式继承

集寄生式继承和组合继承的优点与一身,是实现基本类型继承的最有效方式。

//继承原型
function extend(subType, superType) {
function F(){};
F.prototype = superType.prototype; var prototype = new F;
prototype.constructor = subType;
subType.prototype = prototype;
} //超类方法
function SuperType(name) {
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function() {
return this.name;
} //子类方法
function SubType(name, age) {
SuperType.call(this, name);
this.age = age;
} //继承超类的原型
extend(SubType, SuperType); //子类方法
SubType.prototype.sayAge = function() {
return this.age;
} var instance1 = new SubType("Shelby");
var instance2 = new SubType("Court", 28); instance1.colors.push('black'); alert(instance1.colors); //red,blue,green,black
alert(instance2.colors); //red,blue,green alert(instance1 instanceof SubType); //true
alert(instance1 instanceof SuperType); //true

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

JS 面向对象之继承---多种组合继承的更多相关文章

  1. 三张图搞懂JavaScript的原型对象与原型链 / js继承,各种继承的优缺点(原型链继承,组合继承,寄生组合继承)

    摘自:https://www.cnblogs.com/shuiyi/p/5305435.html 对于新人来说,JavaScript的原型是一个很让人头疼的事情,一来prototype容易与__pro ...

  2. JS面向对象的类 实例化与继承

    JS中 类的声明有两种形式: // 类的声明 function Animal() { this.name = 'name' } // ES6中的class声明 class Animal2 { cons ...

  3. javascript学习笔记--经典继承、组合继承、原型式继承、寄生继承以及寄生组合继承

    经典继承 js中实现经典继承的方式是通过构造函数来实现的,即在子类中对父类调用call方法. function Geometric() { this.time = ""; this ...

  4. 关于JS面向对象、设计模式、以及继承的问题总结

    1.对象:JS中万物皆对象,它是一个泛指 类:对象的具体的细分 (物以类聚,人与群分.具有相同属性和方法的实例的一个集合总称) 实例:某一个类别中具体的一个事物 对象是一个抽象的概念,类似于我们的自然 ...

  5. [js高手之路]从原型链开始图解继承到组合继承的产生

    基于javascript原型链的层层递进查找规则,以及原型对象(prototype)的共享特性,实现继承是非常简单的事情 一.把父类的实例对象赋给子类的原型对象(prototype),可以实现继承 f ...

  6. node.js面向对象实现(二)继承

    http://blog.sina.com.cn/s/blog_b5a53f2e0101nrdi.html 继承是面向对象中非常重要的一个概念,那么在Node.js中如何实现继承呢? node.js在u ...

  7. JS继承之借用构造函数继承和组合继承

    根据少一点套路,多一点真诚这个原则,继续学习. 借用构造函数继承 在解决原型中包含引用类型值所带来问题的过程中,开发人员开始使用一种叫做借用构造函数(constructor stealing)的技术( ...

  8. javascript实现继承3种方式: 原型继承、借用构造函数继承、组合继承,模拟extends方法继承

    javascript中实现继承的三种方式:原型继承.借用构造函数继承.混合继承: /* js当中的继承 js中 构造函数 原型对象 实力对象的关系: 1 构造函数.prototype = 原型对象 2 ...

  9. 深入浅出javascript(十二)继承——构造函数继承和组合继承

    #题记: 有一水果类,抽象出属性包括:name(水果品种),price(价格),id(ID号).现有两个子类,分别为苹果,桔子,希望继承水果父类. 一.构造函数继承 构造函数继承相当把父类的属性在子类 ...

随机推荐

  1. jmxtrans 监控kafka

    jmxtrans 的版本必须 是jmxtrans-268.rpm 以上 如果kafka 为kafka_2.11-0.10.1.0 ,则在 jdk 1.7上使用 kafka_2.12-0.11.0.0 ...

  2. Linux 包管理器

    RPM: rpm(Red-Hat Package Manager) 为 Redhat 提出的包管理器, 用于在 Redhat 及其衍生版本中安装 rpm 格式的软件包 rpm 的优点: 1.简化了源码 ...

  3. 2016级算法第二次上机-C.AlvinZH的儿时梦想——坦克篇

    872 AlvinZH的儿时梦想----坦克篇 思路 简单题.仔细看题,题目意在找到直线穿过的矩形数最小,不能从两边穿过.那么我们只要知道每一行矩形之间的空隙位置就可以了. 如果这里用二维数组记住每一 ...

  4. 复制订阅服务器和 AlwaysOn 可用性组 (SQL Server)

    https://docs.microsoft.com/zh-cn/sql/database-engine/availability-groups/windows/replication-subscri ...

  5. 2D激光SLAM算法比较+cartographer

    Hector slam: Hector slam利用高斯牛顿方法解决scan-matching问题,对传感器要求较高. 缺点:需要雷达(LRS)的更新频率较高,测量噪声小.所以在制图过程中,需要rob ...

  6. 4KM

    ip addr add 10.9.8.100/24 broadcast + dev eth0 /etc/sysconfig/network-scripts/ifcfg-eth0 ifdown eth0 ...

  7. Java - 冒泡排序的基础算法(尚学堂第七章数组)

    /** * 冒泡排序的基础算法 */ import java.util.Arrays; public class TestBubbleSort1 { public static void main(S ...

  8. 溶解shader

    玩神界原罪2,感觉人物被建筑遮挡时,建筑的“溶解”效果很有意思,想实现一下.然后发现连溶解都没实现过,emmmmm....先来把溶解实现了~ 原理就是根据一张噪声图的值是否大于某个阈值,来判断是否丢弃 ...

  9. TortoiseGit学习系列之TortoiseGit是什么?

    写该文章目的 肯定有人会遇到这样的问题: 最近换了一份新工作,新公司的源码管理都是使用GIT,习惯了之前的TFS和SVN进行项目源码管理和团队开发,第一次使用GIT进行团队开发和源码管理,颇有一些不习 ...

  10. Spark standalone模式的安装(spark-1.6.1-bin-hadoop2.6.tgz)(master、slave1和slave2)

     前期博客  Spark运行模式概述 Spark standalone简介与运行wordcount(master.slave1和slave2) 开篇要明白 (1)spark-env.sh 是环境变量配 ...