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 相关文章推荐
看了就知道什么是JSON
Dec 09 Javascript
使用Java实现简单的server/client回显功能的方法介绍
May 03 Javascript
浅析js设置控件的readonly与enabled属性问题
Dec 25 Javascript
jQuery+HTML5实现图片上传前预览效果
Aug 20 Javascript
理解javascript封装
Feb 23 Javascript
创建一个类Person的简单实例
May 17 Javascript
BootStrap实现邮件列表的分页和模态框添加邮件的功能
Oct 13 Javascript
通过AngularJS实现图片上传及缩略图展示示例
Jan 03 Javascript
基于Node.js的WebSocket通信实现
Mar 11 Javascript
JavaScript递归算法生成树形菜单
Aug 15 Javascript
axios中cookie跨域及相关配置示例详解
Dec 20 Javascript
微信小程序实现导航栏和内容上下联动功能代码
Jun 29 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设置页面超时时间解决方法
2015/09/22 PHP
php中namespace use用法实例分析
2016/01/22 PHP
Yii2中SqlDataProvider用法示例
2016/09/22 PHP
PHP 中使用ajax时一些常见错误总结整理
2017/02/27 PHP
分享5个非常有用的Laravel Blade指令
2018/05/30 PHP
Jquery替换已存在于element上的event的方法
2010/03/09 Javascript
Google排名中的10个最著名的 JavaScript库
2010/04/27 Javascript
IE6下出现JavaScript未结束的字符串常量错误的解决方法
2010/11/21 Javascript
js 获取屏幕各种宽高的方法(浏览器兼容)
2013/05/15 Javascript
js实现刷新iframe的方法汇总
2015/04/27 Javascript
javascript实现图片上传前台页面
2015/08/18 Javascript
jQuery旋转插件jqueryrotate用法详解
2016/10/13 Javascript
微信小程序之picker日期和时间选择器
2017/02/09 Javascript
JS实现控制图片显示大小的方法【图片等比例缩放功能】
2017/02/18 Javascript
AngularJS 实现点击按钮获取验证码功能实例代码
2017/07/13 Javascript
将jquery.qqFace.js表情转换成微信的字符码
2017/12/01 jQuery
Postman无法正常返回结果问题解决
2020/08/28 Javascript
js实现圆形菜单选择器
2020/12/03 Javascript
详解如何在vue+element-ui的项目中封装dialog组件
2020/12/11 Vue.js
javascript实现下拉菜单效果
2021/02/09 Javascript
[03:11]不朽宝藏三外观展示
2020/09/18 DOTA
Python安装第三方库的3种方法
2015/06/21 Python
在keras中实现查看其训练loss值
2020/06/16 Python
分布式全文检索引擎ElasticSearch原理及使用实例
2020/11/14 Python
Python3中的tuple函数知识点讲解
2021/01/03 Python
使用HTML5的File实现base64和图片的互转
2013/08/01 HTML / CSS
巴西家用小家电购物网站:Polishop
2016/08/07 全球购物
英国家电直销:Appliances Direct
2016/09/22 全球购物
SQL Server提供的3种恢复模型都是什么? 有什么区别?
2012/05/13 面试题
Why do we need Unit test
2013/01/03 面试题
升职自荐信
2013/11/28 职场文书
yy婚礼主持词
2014/03/14 职场文书
大宝sod蜜广告词
2014/03/21 职场文书
市级绿色学校申报材料
2014/08/25 职场文书
质量负责人岗位职责
2015/02/15 职场文书
中国古代史学名著《战国策》概述
2019/08/09 职场文书