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. 使用 webpack 搭建 React 项目

    简评:相信很多开发者在入门 react 的时候都是使用 create-react-app 或 react-slingshot 这些脚手架来快速创建应用,当有特殊需求,需要修改 eject 出来的 we ...

  2. TCP的坚持定时器

    一.简介 TCP不对ACK报文段进行确认,TCP只确认那些包含有数据的ACK字段. 如果一个确认丢失了,双方就有可能因为等待对方而使得链连接终止: 接收方等待接受数据,因为已经向发送方通告了一个非0的 ...

  3. Linux CentOs 下 安装 mysql nginx redis

    SCP 的使用 来源于: https://blog.csdn.net/qq_30968657/article/details/72912070 scp [参数] <源地址(用户名@IP地址或主机 ...

  4. threejs的学习笔记

    很多时候,我们在开发3d效果的时候,容易搞不清楚x,y,z坐标分别指示哪个方向 在开发threejs的时候可以先把坐标系添加到场景中,起到一个启示作用. js // show axes in the ...

  5. ubuntu16.04 能启动mysql服务

    ubuntu16.04 后, 貌似mysqld在/etc/init.d下,直接执行会报mysqld不在服务中,因此开启mysql服务失败. 所以执行以下命令不能启动mysql服务: /etc/init ...

  6. python学习笔记1.4

    注释不被程序执行的辅助性说明信息- 单行注释:以#开头,其后内容为注释# 这里是单行注释- 多行注释:以'''开头和结尾''' 这是多行注释第一行这是多行注释第二行 ''' 保留字and elif i ...

  7. 991 AlvinZH的奇幻猜想----整数乘积plus(背包DP大作战P)

    914 AlvinZH的奇幻猜想----整数乘积puls 思路 难题.动态规划. 将数字串按字符串输入,处理起来更方便些. dp[i][j]:表示str[0~i]中插入j个乘号时的乘积最大值.状态转移 ...

  8. 批量自动化生成PDF目录标签

    所需软件: 1. FreePic2Pdf(网上很容易找到) 2. python3 3. 天若OCR 链接:https://pan.baidu.com/s/1B9dUr3gc0pv0BSHo5QYGsQ ...

  9. POJ_2155 Matrix 【二维树状数组】

    一.题面 POJ2155 二.分析 楼教主出的题,是二维树状数组非常好的题,还结合了开关问题(开关变化的次数如果为偶数,状态不变,奇数状态相反). 题意就是给了一个二维的坐标平面,每个点初始值都是0, ...

  10. 自动化测试接口PYTHON

      在开发测试中经常会遇到接口迭代和代码重构,一个无关紧要的改动往往会引起整个项目的运行.现有的接口测试中往往只是针对单一接口的测试,可是业务的连贯性是非常紧密的,比如:用户从登陆,获取商品信息,下单 ...