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 相关文章推荐
javascript 面向对象思想 附源码
Jul 07 Javascript
获取焦点时,利用js定时器设定时间执行动作
Apr 02 Javascript
ymPrompt的doHandler方法来实现获取子窗口返回值的方法
Jun 25 Javascript
原生js实现查找/添加/删除/指定元素的class
Apr 12 Javascript
浅谈JavaScript中的作用域和闭包问题
Jul 07 Javascript
jquery append 动态添加的元素事件on 不起作用的解决方案
Jul 30 Javascript
jQuery+ajax实现文章点赞功能的方法
Dec 31 Javascript
浅谈angularjs依赖服务注入写法的注意点
Apr 24 Javascript
深入理解React Native原生模块与JS模块通信的几种方式
Jul 24 Javascript
JS库 Highlightjs 添加代码行号的实现代码
Sep 13 Javascript
webpack项目使用eslint建立代码规范实现
May 16 Javascript
微信小程序左滑删除实现代码实例
Sep 16 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学习资源和链接.
2006/12/05 PHP
Ajax PHP简单入门教程代码
2008/04/25 PHP
ThinkPHP中处理表单中的注意事项
2014/11/22 PHP
php可变长参数处理函数详解
2017/02/22 PHP
使用PHPExcel实现数据批量导出为excel表格的方法(必看)
2017/06/09 PHP
thinkphp5使html5实现动态跳转的例子
2019/10/16 PHP
JavaScript confirm选择判断
2008/10/18 Javascript
javascript下arguments,caller,callee,call,apply示例及理解
2009/12/24 Javascript
ASP.NET jQuery 实例15 通过控件CustomValidator验证CheckBoxList
2012/02/03 Javascript
Node.js生成HttpStatusCode辅助类发布到npm
2013/04/09 Javascript
js模仿windows桌面图标排列算法具体实现(附图)
2013/06/16 Javascript
JavaScript操纵窗口的方法小结
2013/06/28 Javascript
JavaScript中通过prototype属性共享属性和方法的技巧实例
2015/03/13 Javascript
纯JavaScript实现的分页插件实例
2015/07/14 Javascript
Javascript技术栈中的四种依赖注入详解
2016/02/23 Javascript
利用Javascript实现简单的转盘抽奖
2017/02/13 Javascript
Vue无限滑动周选择日期的组件的示例代码
2018/07/18 Javascript
JS散列表碰撞处理、开链法、HashTable散列示例
2019/02/08 Javascript
浅谈对于react-thunk中间件的简单理解
2019/05/01 Javascript
Vue数据绑定实例写法
2019/08/06 Javascript
vue element 生成无线级左侧菜单的实现代码
2019/08/21 Javascript
python解析html开发库pyquery使用方法
2014/02/07 Python
centos 下面安装python2.7 +pip +mysqld
2014/11/18 Python
详解python之heapq模块及排序操作
2019/04/04 Python
python numpy实现多次循环读取文件 等间隔过滤数据示例
2020/03/14 Python
numpy中生成随机数的几种常用函数(小结)
2020/08/18 Python
Nayomi官网:沙特阿拉伯王国睡衣和内衣品牌
2020/12/19 全球购物
函授本科毕业自我鉴定
2013/10/09 职场文书
2014年数学教研组工作总结
2014/12/06 职场文书
高中生自我评价范文2015
2015/03/03 职场文书
大学生自荐信范文
2015/03/05 职场文书
创业计划书之密室逃脱
2019/11/08 职场文书
CSS filter 有什么神奇用途
2021/05/25 HTML / CSS
pytorch finetuning 自己的图片进行训练操作
2021/06/05 Python
vite+vue3.0+ts+element-plus快速搭建项目的实现
2021/06/24 Vue.js
Django中session进行权限管理的使用
2021/07/09 Python