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 相关文章推荐
从URL中提取参数与将对象转换为URL查询参数的实现代码
Jan 12 Javascript
js实现局部页面打印预览原理及示例代码
Jul 03 Javascript
jQuery+CSS实现一个侧滑导航菜单代码
May 09 Javascript
关于JS中setTimeout()无法调用带参函数问题的解决方法
Jun 21 Javascript
JS HTML5实现拖拽移动列表效果
Aug 27 Javascript
Vue.js 2.0窥探之Virtual DOM到底是什么?
Feb 10 Javascript
AngularJS自定义指令实现面包屑功能完整实例
May 17 Javascript
JS获取数组中出现次数最多及第二多元素的方法
Oct 27 Javascript
深入了解javascript 数组的sort方法
Jun 01 Javascript
详解如何在Vue里建立长按指令
Aug 20 Javascript
记录一次完整的react hooks实践
Mar 11 Javascript
node.js实现上传文件功能
Jul 15 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会话(Session)实现用户登陆功能
2013/06/29 PHP
php延迟静态绑定实例分析
2015/02/08 PHP
PHP session文件独占锁引起阻塞问题解决方法
2015/05/12 PHP
PHP利用APC模块实现大文件上传进度条的方法
2015/10/29 PHP
PHP查询分页的实现代码
2017/06/09 PHP
PHP registerXPathNamespace()函数讲解
2019/02/03 PHP
从Ajax到JQuery Ajax学习
2007/02/14 Javascript
js导出txt示例代码
2014/01/14 Javascript
jQuery中:radio选择器用法实例
2015/01/03 Javascript
jQuery实现动画效果circle实例
2015/08/06 Javascript
JS模仿腾讯图片站的图片翻页按钮效果完整实例
2016/06/21 Javascript
使用BootStrap进行轮播图的制作
2017/01/06 Javascript
JSON与JS对象的区别与对比
2017/03/01 Javascript
vue-dialog的弹出层组件
2020/05/25 Javascript
jQuery 中msgTips 顶部弹窗效果实现代码
2017/08/14 jQuery
基于node下的http小爬虫的示例代码
2018/01/11 Javascript
javascript实现函数柯里化与反柯里化过程解析
2019/10/08 Javascript
微信小程序开发中var that =this的用法详解
2020/01/18 Javascript
基于vue的tab-list类目切换商品列表组件的示例代码
2020/02/14 Javascript
nodejs+koa2 实现模仿springMVC框架
2020/10/21 NodeJs
Python中的两个内置模块介绍
2015/04/05 Python
Python json 错误xx is not JSON serializable解决办法
2017/03/15 Python
python 如何快速找出两个电子表中数据的差异
2017/05/26 Python
python批量修改图片后缀的方法(png到jpg)
2018/10/25 Python
django 多数据库及分库实现方式
2020/04/01 Python
Python 如何调试程序崩溃错误
2020/08/03 Python
html5指南-4.使用Geolocation实现定位功能
2013/01/07 HTML / CSS
WEB控件及HTML服务端控件能否调用客户端方法?如果能,请解释如何调用?
2015/08/25 面试题
网页设计个人找工作求职信
2013/11/28 职场文书
小学生期末自我鉴定
2014/01/19 职场文书
领导干部学习“三严三实”思想汇报
2014/09/15 职场文书
男方婚前保证书
2015/02/28 职场文书
销售区域经理岗位职责
2015/04/10 职场文书
少年雷锋观后感
2015/06/10 职场文书
用人单位的规章制度,怎样制定才是有效的?
2019/07/09 职场文书
redis数据结构之压缩列表
2022/03/21 Redis