JavaScript模拟实现继承的方法


Posted in Javascript onMarch 30, 2015

本文实例讲述了JavaScript模拟实现继承的方法。分享给大家供大家参考。具体分析如下:

我们都知道,在JavaScript中只能模拟实现OO中的"类",也就意味着,在JavaScript中没有类的继承。我们也只能通过在原对象里添加或改写属性来模拟实现。

先定义一个父类,

//父类
function ParentClass() {
 this.className = "ParentClass";
 this.auth = "Auth";
 this.version = "V1.0";
 this.parentClassInfo = function () {
 return this.className + "\n" + this.auth + "\n" + this.version;
 }
}

一、prototype 实现:

//子类
//1、prototype继承
function ChildClassByPrototype() {
 this.date = "2013-07-26";
 this.classInfo = function () {
  return this.parentClassInfo() + "\n" + this.date;
 }
}
ChildClassByPrototype.prototype = new ParentClass();
var cctest1 = new ChildClassByPrototype();
cctest1.parentClassInfo();
cctest1.classInfo();

这种方式很简单,只需把父类的实例赋值给子类的prototype属性就行了,然后子类就可以使用父亲的方法和属性了。这里其实是用到了原型链向上查找的特性,比如这个例子中的 cctest1.parentClassInfo() 方法,JavaScript会先在ChildClassByPrototype的实例中查找是否有parentClassInfo()方法,子类中没有,所以继续查找ChildClassByPrototype.prototype属性,而其prototype属性的值是ParentClass的一个实例,该实例有parentClassInfo()方法,于是查找结束,调用成功。

二、apply 实现:

//2、apply继承
function ChildClassByApply() {
 ParentClass.apply(this, new Array());
 //ParentClass.apply(this, []);
 this.date = "2013-07-26";
 this.classInfo = function () {
  return this.parentClassInfo() + "\n" + this.date;
 }
}

JavaScript中的apply可以理解为用A方法替换B方法,第一个参数为B方法的对象本身,第二个参数为一个数组,该数组内的值为需要传递给A方法对应的参数列表,如果参数为空,即没有参数传递,可通过 new Array()、[] 来传递。

三、call + prototype 实现:

//3、call+prototype继承
function ChildClassByCall() {
 ParentClass.call(this, arguments);
 this.date = "2013-07-26";
 this.classInfo = function () {
  return this.parentClassInfo() + "\n" + this.date;
 }
}
ChildClassByCall.prototype = new ParentClass();

call和apply作用类似,即都是用A方法替换B方法,只是传递的参数不一样,call方法的第一个参数为B方法的对象本身,后续的参数则不用Array包装,需直接依次进行传递。既然作用差不多,为何多了一句 原型赋值呢?这是因为call方法只实现了方法的替换而没有对对象属性进行复制操作。

每种方法都有其适用环境,比如,如果父类带有有参构造函数:

function ParentClass(className, auth, version) {
 this.className = className;
 this.auth = auth;
 this.version = version;
 this.parentClassInfo = function () {
 return this.className + "\n" + this.auth + "\n" + this.version;
 }
}

这种情况下,prototype就不适用了,可选用apply或call;

function ChildClassByApply(className, auth, version) {
 ParentClass.apply(this, [className, auth, version]);
 this.date = "2013-07-26";
 this.classInfo = function () {
  return this.parentClassInfo() + "\n" + this.date;
 }
}
function ChildClassByCall(className, auth, version) {
 ParentClass.call(this, arguments[0], arguments[1], arguments[2]);
 //ParentClass.call(this, className, auth, version);
 this.date = "2013-07-26";
 this.classInfo = function () {
  return this.parentClassInfo() + "\n" + this.date;
 }
}
ChildClassByCall.prototype = new ParentClass();

实例化:

var cctest2 = new ChildClassByApply("ParentClass", "Auth", "V1.0");
var cctest3 = new ChildClassByCall("ParentClass", "Auth", "V1.0");

在apply和call中,又该如何取舍呢?在OO的继承中,子类继承于父类,那么它应该也是父类的类型。即,ChildClassByCall、ChildClassByApply应该也是ParentClass类型,但我们用"instanceof"检测一下就会发现,通过apply继承的子类,并非ParentClass类型。所以,我们建议用call + prototype 来模拟实现继承。据说,Google Map API 的继承就是使用这种方式哟。

希望本文所述对大家的javascript程序设计有所帮助。

Javascript 相关文章推荐
JQuery 学习笔记 选择器之六
Jul 23 Javascript
js下写一个事件队列操作函数
Jul 19 Javascript
js修改input的type属性及浏览器兼容问题探讨与解决
Jan 23 Javascript
Angular设置title信息解决SEO方面存在问题
Aug 19 Javascript
微信小程序实现美团菜单
Jun 06 Javascript
微信开发之企业付款到银行卡接口开发的示例代码
Sep 18 Javascript
layui输入框只允许输入中文且判断长度的例子
Sep 18 Javascript
JavaScript使用localStorage存储数据
Sep 25 Javascript
vue之debounce属性被移除及处理详解
Nov 13 Javascript
如何实现echarts markline标签名显示自己想要的
Jul 20 Javascript
Vue-CLI 3 scp2自动部署项目至服务器的方法
Jul 24 Javascript
js+canvas实现画板功能
Sep 13 Javascript
jQuery制作可自定义大小的拼图游戏
Mar 30 #Javascript
JS实现向表格中动态添加行的方法
Mar 30 #Javascript
JS实现向表格行添加新单元格的方法
Mar 30 #Javascript
JS实现控制表格行文本对齐的方法
Mar 30 #Javascript
JS实现控制表格行内容垂直对齐的方法
Mar 30 #Javascript
JS实现控制表格内指定单元格内容对齐的方法
Mar 30 #Javascript
JS实现控制表格单元格垂直对齐的方法
Mar 30 #Javascript
You might like
php遍历文件夹和文件列表示例分享
2014/03/11 PHP
ThinkPHP结合ajax、Mysql实现的客户端通信功能代码示例
2014/06/23 PHP
php中的mongodb select常用操作代码示例
2014/09/06 PHP
关于URL最大长度限制的相关资料查证
2014/12/23 PHP
PHP实现多图上传(结合uploadify插件)思路分析
2016/11/30 PHP
PHP验证终端类型是否为手机的简单实例
2017/02/07 PHP
用Javascript做flash做的事..才完成的一个类.Auntion Action var 0.1
2007/02/23 Javascript
js substr、substring和slice使用说明小记
2011/09/15 Javascript
JS验证日期的格式YYYY-mm-dd 具体实现
2013/06/29 Javascript
js中substr,substring,indexOf,lastIndexOf的用法小结
2013/12/27 Javascript
JavaScript按值删除数组元素的方法
2015/04/24 Javascript
javascript与Python快速排序实例对比
2015/08/10 Javascript
jquery实现漫天雪花飞舞的圣诞祝福雪花效果代码分享
2015/08/20 Javascript
Nodejs下DNS缓存问题浅析
2016/11/16 NodeJs
vuejs事件中心管理组件间的通信详解
2017/08/09 Javascript
在微信小程序中使用图表的方法示例
2019/04/25 Javascript
8 个有用的JS技巧(推荐)
2019/07/03 Javascript
在nodejs中创建child process的方法
2021/01/26 NodeJs
[02:17]《辉夜杯》TRG战队巡礼
2015/10/26 DOTA
[53:15]2018DOTA2亚洲邀请赛3月29日 小组赛A组 LGD VS TNC
2018/03/30 DOTA
[56:14]Fnatic vs OG 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
[44:30]完美世界DOTA2联赛PWL S2 GXR vs Magma 第一场 11.25
2020/11/26 DOTA
Python实现端口检测的方法
2018/07/24 Python
PyCharm2018 安装及破解方法实现步骤
2019/09/09 Python
什么是Python中的匿名函数
2020/06/02 Python
Pytorch 卷积中的 Input Shape用法
2020/06/29 Python
美国在线旅行社:Crystal Travel
2018/09/11 全球购物
西班牙土拨鼠床垫公司,感觉在云端:Marmota
2019/03/18 全球购物
介绍一下Prototype的$()函数,$F()函数,$A()函数都是什么作用?
2014/03/05 面试题
幼儿园秋游活动方案
2014/01/21 职场文书
社区学习十八大感想
2014/01/22 职场文书
《桃花心木》教学反思
2014/02/17 职场文书
2015年八一建军节演讲稿
2015/03/19 职场文书
用 Python 定义 Schema 并生成 Parquet 文件详情
2021/09/25 Python
mysql如何能有效防止删库跑路
2021/10/05 MySQL
详解Go语言中配置文件使用与日志配置
2022/06/01 Golang