我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧!

上回我们说到组合继承在使用构造函数继承时继承了一遍父类构造函数,在实现子类原型的类式继承时又调用了一遍父类构造函数。因此父类构造函数调用了两遍,并不算最优的继承方式,下面我们再来介绍更好的方式。

原型式继承

首先我们声明一个对象

function proObject(o){
//声明一个过渡函数对象
function Obj(){}
//过渡对象的原型继承父对象
Obj.prototype=o;
//返回过渡对象的一个实例,该实例的原型继承了父对象
return new Obj();
}

是不是觉得这种方式和我们之前讲到的类式继承很相似,的确原型式继承是对类式继承的一个封装,其中的过渡对象就相当于类式继承中的子类,过渡的意义主要是想返回一个新的实例化对象。

Object.create()方法就是原型式继承。

那么类式继承的那些缺点是否也会在原型式继承中提现出来呢?答案是肯定的,我们来看看下面的例子

var Students={
admissionTime:"2017",
hobby:["唱歌","画画"]
};
var student1=proObject(Students);
student1.admissionTime="2016";
student1.hobby.push("游泳"); var student2=proObject(Students);
student2.admissionTime="2015";
student2.hobby.push("看书");

接着我们把结果打印出来看看

console.log(student1.admissionTime);//2016
console.log(student1.hobby);//["唱歌","画画","游泳","看书"] console.log(student2.admissionTime);//2015
console.log(student2.hobby);//["唱歌","画画","游泳","看书"] console.log(Students.admissionTime);//2017
console.log(Students.hobby);//["唱歌","画画","游泳","看书"]

还是和之前的类式继承一样值类型的属性被复制,引用类型的属性被共用了。所以在原型式继承的基础上做了些增强出现了下面的继承方式。

寄生式继承

寄生式继承其实就是对原型式继承的第二次封装,并且在第二次封装过程中对继承的对象进行了拓展,这样新创建的对象不仅仅有父类中的睡醒和方法,而且还添加了新的属性和方法。

首先我们先声明基类对象

var Students={};
function CreateStu(obj){
//通过原型式继承方式创建新对象
var stu=proObject(obj);
//扩展新对象
stu.getAdmissionTime=function(){
console.log(stu.admissionTime);
};
//返回拓展后的新对象
return stu;
}
var student1=CreateStu(Students);
student1.admissionTime="2016";
student1.hobby.push("游泳"); var student2=CreateStu(Students);
student2.admissionTime="2015";
student2.hobby.push("看书");

接着我们把结果打印出来看看

student1.getAdmissionTime();//2016
console.log(student1.hobby);//["唱歌","画画","游泳","看书"] student2.getAdmissionTime();//2015
console.log(student2.hobby);//["唱歌","画画","游泳","看书"]

这种类型的继承就跟他的名字一样,像寄生虫一样寄托于某个对象内部生长,当然这种思想是为了我们接下来的继承模式的实现

寄生组合式继承

我们之前讲到的组合式继承,是将类式继承和构造函数继承组合使用,但这种方式有个问题,父类构造函数调用了两遍而且子类不是父类的实例,子类的原型才是父类的实例,所以才有了我们现在讲到的寄生组合式继承。

那么寄生组合式继承又是哪两种模式的组合呢?

由名字我们可以看出,寄生当然是指寄生式继承而寄生式继承又依托于原型式继承,我们之前讲到原型式继承和类式继承相似,所以另一种继承模式就是构造函数继承。

寄生式继承有些特殊,他处理的不是对象,而是类的原型。

下面我们来看一下具体的实现步骤

function parasiticType(ParentClass,ChildClass){
//复制一份父类的原型保存在变量中
var parent=proObject(ParentClass.prototype);
//修正因为重写子类原型导致子类的constructor属性被修改
parent.constructor=ChildClass;
//设置子类的原型
ChildClass.prototype=parent;
}

组合式继承中,通过构造函数继承的属性和方法是没有问题的,所以这里我们主要探究通过寄生式继承重新继承父类的原型。

我们需要继承的仅仅是父类的原型,不再需要调用父类的构造函数。

所以我们需要的其实就只有父类原型对象的副本,而这个副本我们可以通过原型式继承得到,但是我们直接赋值给子类会有问题的,因为对父类原型对象复制得到的复制对象parent中的constructor指向的不是ChildClass子类对象,

因此在寄生式继承中,我们要对复制对象parent做一次增强,修复器constructor属性指向不正确的问题,最后我们将得到的复制对象P赋值给子类的原型,这样子类的原型就继承了类的原型并且没有执行父类的构造函数。

constructor是一个属性,当创建一个函数或者对象时都会为其创建一个原型对象prototype,在prototype对象中,又会想函数中创建this一样创建一个constructor属性,那么constructor属性指向的就是拥有整个原型对象的函数或者对象。

下面我们来看一下具体实现的步骤

首先我们定义一个父类

function ParentClass(id){
//引用类型的公有属性
this.parentValue=['C#','JAVA','PHP'];
//值类型公有属性
this.id=id;
}

接着我们声明父类的原型方法

ParentClass.prototype.getParentValue=function(){
console.log(this.parentValue);
}

下面我们声明子类

function ChildClass(id,childValue){
//构造函数式继承父类
ParentClass.call(this,id);
//子类新增属性
this.childValue=childValue;
}

寄生式继承父类原型

parasiticType(ParentClass,ChildClass);

子类新增原型方法

ChildClass.prototype.getChildValue=function(){
console.log(this.time);
}

接着我们创建两个测试方法

var test1=new ChildClass(1,"张三");
var test2=new ChildClass(2,"李四");

接着我们来测试一下

test1.parentValue.push("C++");
console.log(test1.parentValue);//["C#", "JAVA", "PHP", "C++"]
console.log(test2.parentValue);//["C#", "JAVA", "PHP"]
test1.getParentValue();//["C#", "JAVA", "PHP", "C++"]
test1.getChildValue();//张三
test2.getParentValue();//["C#", "JAVA", "PHP"]
test2.getChildValue();//李四

这里我们要注意一点,子类再想添加原型方法必须通过prototype对象,通过点语法的形式一个一个添加方法,否则直接赋予对象就会覆盖掉从父类原型继承的对象。

到这里我们的继承大致就介绍完了,下面我们开始介绍如何使用javascript实现多态

多态

在面向对象的语言中,我们通过方法重载来实现多态,在javascript中我们可以对传入的参数做判断实现多种调用方式从而达到实现多态的效果。

首先我们定义一个方法

function polymorphism(){
//获取参数
var argument=arguments;
//获取参数长度
var len=argument.length;
switch(len){
//如果没有参数
case 0:
return 0;
//如果只有一个参数
case 1:
return 1;
//如果有两个参数
case 2:
return 2;
}
}

我们来试一试

console.log(polymorphism());//0
console.log(polymorphism(1));//1
console.log(polymorphism(1,2));//2

这样我们就很简单的实现了多态的效果,好了这就是本次分享的全部内容,下一章我们开始正式进入javascript设计模式。

也谢谢大家看到这里:)如果你觉得我的分享还可以请点击推荐,分享给你的朋友让我们一起进步~

好了以上就是本次分享的全部内容,本次示例参考自JavaScript设计模式一书,让我们一点点积累一点点成长,希望对大家有所帮助。

再起航,我的学习笔记之JavaScript设计模式04的更多相关文章

  1. 再起航,我的学习笔记之JavaScript设计模式02

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 我们 ...

  2. 再起航,我的学习笔记之JavaScript设计模式01

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 在通 ...

  3. 再起航,我的学习笔记之JavaScript设计模式03

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 上一 ...

  4. 再起航,我的学习笔记之JavaScript设计模式05(简单工程模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前几 ...

  5. 再起航,我的学习笔记之JavaScript设计模式06(工厂方法模式)

    上一次已经给大家介绍了简单工厂模式,相信大家对创建型设计模式有了初步的了解,本次我将给大家介绍的是工厂方法模式. 工厂方法模式 工厂方法模式(Factory Method):通过对产品类的抽象使其创建 ...

  6. 再起航,我的学习笔记之JavaScript设计模式05(简单工厂模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前几 ...

  7. 再起航,我的学习笔记之JavaScript设计模式06(抽象工厂模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前两 ...

  8. 再起航,我的学习笔记之JavaScript设计模式08(建造者模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前几 ...

  9. 再起航,我的学习笔记之JavaScript设计模式09(原型模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 我们 ...

随机推荐

  1. 关于MATLAB收集人工鼠标移动轨迹的坐标

    首先需要设计一个用户图形界面的函数,这个图形界面被用于在其上面绘制轨迹并记录当时的坐标. 该回响函数应包含:鼠标按下时,鼠标移动时,和鼠标释放时的反应命令.当然网上有有相关的开源 程序,但是有缺陷(该 ...

  2. mybatis 查询 xml list参数

    mybatis 查询 xml list参数: <select id="getByIds" resultType="string" parameterTyp ...

  3. java网络编程之socket

    网络编程是什么 网络编程的本质是两个设备之间的数据交换,当然,在计算机网络中,设备主要指计算机.数据传递本身没有多大的难度,不就是把一个设备中的数据发送给两外一个设备,然后接受另外一个设备反馈的数据. ...

  4. Java面试常考------------------------垃圾收集算法

    对于Java系学生而言,Java虚拟机中的垃圾收集算法是一个很重要的面试考点. 常用的垃圾收集算法主要可划分为以下三类: 1. 标记-清除算法 标记清除算法是一种比较简单的方法,直接标记内存中待回收的 ...

  5. ASP.NET Core 四种释放 IDisposable 对象的方法

    本文翻译自<Four ways to dispose IDisposables in ASP.NET Core>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! IDispos ...

  6. vijos1027题解

    题目: 当大家在考场中接受考验(折磨?)的时候,小呆正在悠闲(欠扁)地玩一个叫"最初梦想"的游戏.游戏描述的是一个叫pass的有志少年在不同的时空穿越对抗传说中的大魔王chines ...

  7. Mysql连接出错问题

    1.java 提示:java.lang.ClassNotFoundException: com.mysql.jdbc.Driver 处理:导入mysql-connector-java-5.1.7-bi ...

  8. 接口开发,tp5结合swagger-ui安装方法

    今天看到老java用的swagger提供接口,美观好用,方便维护,不是写好接口之后再写接口文档,麻烦的要死.网上找了找结合php的方法,在此记录一下,以后再开发接口就可以方便很多了. Swagger的 ...

  9. CSS3-loading动画(四)

    图片看的效果真是不行,还是戳下面网址看吧 在线示例:http://liyunpei.xyz/loading.html 十七.效果十七 三个小球,纵向居中,间距撑开,依次改变小球的translateY的 ...

  10. 第一章:selenium + java 环境安装

    1. 首先安装的是 jdk ,推荐安装的是   JDK 版本是 1.7 2.  安装 JDK 步骤: 第一步: 第二步: 第三步: 配置 JDK 环境变量,点击 我的电脑-右键-高级-环境变量. 第五 ...