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的Tab选项框效果代码(插件)
Mar 01 Javascript
下拉列表选择项的选中在不同浏览器中的兼容性问题探讨
Sep 18 Javascript
jQuery照片伸缩效果不影响其他元素的布局
May 09 Javascript
使用HTML+CSS+JS制作简单的网页菜单界面
Jul 27 Javascript
jQuery实现div横向拖拽排序的简单实例
Jul 13 Javascript
基于JavaScript实现滑动门效果
Mar 16 Javascript
Vue.js实战之通过监听滚动事件实现动态锚点
Apr 04 Javascript
JS运动特效之任意值添加运动的方法分析
Jan 24 Javascript
js经验分享 JavaScript反调试技巧
Mar 10 Javascript
浅谈Vue内置component组件的应用场景
Mar 27 Javascript
详解基于Vue2.0实现的移动端弹窗(Alert, Confirm, Toast)组件
Aug 02 Javascript
Vue Object 的变化侦测实现代码
Apr 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
用来解析.htpasswd文件的PHP类
2012/09/05 PHP
PHP生成随机密码类分享
2014/06/25 PHP
php使用pack处理二进制文件的方法
2014/07/03 PHP
PHP可变变量学习小结
2015/11/29 PHP
PHP实现创建微信自定义菜单的方法示例
2017/07/14 PHP
PHP仿tp实现mvc框架基本设计思路与实现方法分析
2018/05/23 PHP
thinkPHP和onethink微信支付插件分享
2019/08/11 PHP
php扩展开发入门demo示例
2019/09/23 PHP
javascript RadioButtonList获取选中值
2009/04/09 Javascript
Jjcarousellite 实现图片列表滚动的简单实例
2013/11/29 Javascript
解决JS中乘法的浮点错误的方法
2014/01/03 Javascript
关于javaScript注册click事件传递参数的不成功问题
2014/07/18 Javascript
Jquery修改页面标题title其它JS失效的解决方法
2014/10/31 Javascript
jQuery实现的多级下拉菜单效果代码
2015/08/24 Javascript
jquery获取所有选中的checkbox实现代码
2016/05/26 Javascript
jQuery Easyui使用(一)之可折叠面板的布局手风琴菜单
2016/08/17 Javascript
实例解析angularjs的filter过滤器
2016/12/14 Javascript
详解Vue2.0里过滤器容易踩到的坑
2017/06/01 Javascript
angular2+node.js express打包部署的实战
2017/07/27 Javascript
用js屏蔽被http劫持的浮动广告实现方法
2017/08/10 Javascript
使用Bootstrap和Vue实现用户信息的编辑删除功能
2017/10/25 Javascript
解决angularJS中input标签的ng-change事件无效问题
2018/09/13 Javascript
Node.js系列之连接DB的方法(3)
2019/08/30 Javascript
Python3遍历目录树实现方法
2015/05/22 Python
Python如何实现守护进程的方法示例
2017/02/08 Python
python并发2之使用asyncio处理并发
2017/12/21 Python
在python中pandas的series合并方法
2018/11/12 Python
在matplotlib的图中设置中文标签的方法
2018/12/13 Python
python turtle库画一个方格和圆实例
2019/06/27 Python
Python获取时间范围内日期列表和周列表的函数
2019/08/05 Python
如何基于Python + requests实现发送HTTP请求
2020/01/13 Python
怎样从/向数据文件读/写结构
2014/11/23 面试题
自动化系在校本科生求职信
2013/10/23 职场文书
宝宝周岁宴答谢词
2014/01/26 职场文书
员工保密承诺书
2014/05/28 职场文书
Mysql查询时间区间日期列表,不会由于数据表数据影响
2022/04/19 MySQL