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动态给table添加、删除行 改进版
Jan 19 Javascript
Bootstrap基本插件学习笔记之折叠(22)
Dec 08 Javascript
jQuery:unbind方法的使用详解
Aug 14 jQuery
Mongoose实现虚拟字段查询的方法详解
Aug 15 Javascript
JS Input里添加小图标的两种方法
Nov 11 Javascript
使用node打造自己的命令行工具方法教程
Mar 26 Javascript
JavaScript高级函数应用之分时函数实例分析
Aug 03 Javascript
详解React中传入组件的props改变时更新组件的几种实现方法
Sep 13 Javascript
jsonp跨域获取百度联想词的方法分析
May 13 Javascript
解决$store.getters调用不执行的问题
Nov 08 Javascript
element-ui中按需引入的实现
Dec 25 Javascript
vue动态设置路由权限的主要思路
Jan 13 Vue.js
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
2020年4月放送决定!第2期TV动画《邪神酱飞踢》视觉图&主题曲情报公开!
2020/03/06 日漫
世界收音机发展史
2021/03/01 无线电
PHP获取当前url的具体方法全面解析
2013/11/26 PHP
PHP中file_get_contents高?用法实例
2014/09/24 PHP
Locate a File Using a File Open Dialog Box
2007/06/18 Javascript
JSON 学习之JSON in JavaScript详细使用说明
2010/02/23 Javascript
JS简单实现元素复制示例附图
2013/11/19 Javascript
轻松使用jQuery双向select控件Bootstrap Dual Listbox
2015/12/13 Javascript
Vue.js学习笔记之 helloworld
2016/08/14 Javascript
ES6新特性之模块Module用法详解
2017/04/01 Javascript
原生javascript实现分页效果
2017/04/21 Javascript
Nodejs读取文件时相对路径的正确写法(使用fs模块)
2017/04/27 NodeJs
node简单实现一个更改头像功能的示例
2017/12/29 Javascript
详解如何使用babel进行es6文件的编译
2018/05/29 Javascript
JavaScript数据结构与算法之二叉树插入节点、生成二叉树示例
2019/02/21 Javascript
少女风vue组件库的制作全过程
2019/05/15 Javascript
vue+elementUI组件table实现前端分页功能
2020/11/15 Javascript
[00:12]2018DOTA2亚洲邀请赛 Sccc亮相SOLO赛,今年他又会有什么样的战绩?
2018/04/06 DOTA
Python3之简单搭建自带服务器的实例讲解
2018/06/04 Python
python 对给定可迭代集合统计出现频率,并排序的方法
2018/10/18 Python
python实现微信自动回复及批量添加好友功能
2019/07/03 Python
python pycharm的安装及其使用
2019/10/11 Python
python logging添加filter教程
2019/12/24 Python
利用django model save方法对未更改的字段依然进行了保存
2020/03/28 Python
详解window.open被浏览器拦截的解决方案
2019/07/18 HTML / CSS
英国家电购物网站:Sonic Direct
2019/03/26 全球购物
什么是聚集索引和非聚集索引
2012/01/17 面试题
大学生简历的个人自我评价
2013/12/04 职场文书
2014年关于两会精神的心得体会
2014/03/17 职场文书
党员创先争优活动总结
2014/05/04 职场文书
创先争优活动党员公开承诺书
2014/08/29 职场文书
交通事故委托书范本精选
2014/10/04 职场文书
2014年挂职干部工作总结
2014/12/06 职场文书
2015年教务工作总结
2015/05/23 职场文书
Python中threading库实现线程锁与释放锁
2021/05/17 Python
对PyTorch中inplace字段的全面理解
2021/05/22 Python