我的学习笔记是根据我的学习情况来定期更新的,预计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. Linux网络服务12——NFS共享服务

    Linux网络服务12--NFS共享服务 一.NFS简介 端口号:TCP.UDP 111端口 NFS(Network File System)网络文件系统,是一种基于TCP/IP传输的网络文件系统协议 ...

  2. Swift基础语法

    简介 特点 (1)优于OC,快速,安全 (2)取消了预编译指令包括宏定义(OC用的太多了) (3)取消了OC指针和不安全访问的使用(看不到星星了) (4)舍弃 Objective-C 早期应用 Sma ...

  3. Notepad++中过滤掉的正则方式

    2 => 'ashadv'3 => 'aogro'4 => 'aogs'5 => 'ashamw'6 => 'arc'8 => 'gtsatq'9 => 'b ...

  4. vue 基础-->进阶 教程(2): 指令、组件

    第二章 建议学习时间4小时  课程共3章 前面的nodejs教程并没有停止更新,因为node项目需要用vue来实现界面部分,所以先插入一个vue教程,以免不会的同学不能很好的完成项目. 本教程,将从零 ...

  5. nuget挂了吗?

    [nuget.org] Unable to load the service index for source https://api.nuget.org/v3/index.json. 发送请求时出错 ...

  6. DB数据导出工具分享

    一个根据数据库链接字符串,sql语句 即可将结果集导出到Excel的工具 分享,支持sqlserver,mysql. 前因 一个月前朋友找到我,让我帮忙做一个根据sql导出查询结果到Excel的工具( ...

  7. Socket 文件传输

    服务端 1.控件:TServerSocket 2.OnClientRead事件处理 procedure TMainForm.ssClientRead(Sender: TObject; Socket: ...

  8. MySQl开发和生产环境索引对比

    --1.创建索引信息表create table `t_index_update` (  `table_name` varchar(20) COLLATE gbk_bin DEFAULT NULL,  ...

  9. Java ee el表达式

    以前在开发的时候,偶尔会遇到jsp页面不支持el表达式的情况. 这个的原因是因为El功能被关闭了, 当时的解决办法是关闭忽略.isELIgnored 设设置 但是为什么有时候不用设置也可以了呢.发现原 ...

  10. CJOJ 1943 【重庆八中模拟赛】寻找代表元(二分图最大匹配)

    CJOJ 1943 [重庆八中模拟赛]寻找代表元(二分图最大匹配) Description 八中一共有n个社团,分别用1到n编号. 八中一共有m个人,分别用1到m编号.每个人可以参加一个或多个社团,也 ...