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 ui 1.7更新小结
Aug 15 Javascript
jQuery中add实现同时选择两个id对象
Oct 22 Javascript
JavaScript高级程序设计 扩展--关于动态原型
Nov 09 Javascript
JavaScript判断变量是否为undefined的两种写法区别
Dec 04 Javascript
jQuery操作Table技巧大汇总
Jan 23 Javascript
Angularjs---项目搭建图文教程
Jul 08 Javascript
微信小程序 教程之条件渲染
Oct 18 Javascript
JS与jQuery实现子窗口获取父窗口元素值的方法
Apr 17 jQuery
vue cli 全面解析
Feb 28 Javascript
vue.js 实现点击展开收起动画效果
Jul 07 Javascript
ES6知识点整理之数组解构和字符串解构的应用示例
Apr 17 Javascript
jquery添加div实现消息聊天框
Feb 08 jQuery
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 模拟POST|GET操作实现代码
2010/07/20 PHP
利用PHP扩展vld查看PHP opcode操作步骤
2013/03/04 PHP
php生成图形验证码几种方法小结
2013/08/15 PHP
PHP 函数call_user_func和call_user_func_array用法详解
2014/03/02 PHP
Laravel中批量赋值Mass-Assignment的真正含义详解
2017/09/29 PHP
javascrpt绑定事件之匿名函数无法解除绑定问题
2012/12/06 Javascript
innerText 使用示例
2014/01/23 Javascript
JavaScript中的acos()方法使用详解
2015/06/14 Javascript
关于JavaScript作用域你想知道的一切
2016/02/04 Javascript
JavaScript function函数种类详解
2016/02/22 Javascript
省市选择的简单实现(基于zepto.js)
2016/06/21 Javascript
javascript与jquery动态创建html元素示例
2016/07/25 Javascript
js 获取站点应用名的简单实例
2016/08/18 Javascript
BootStrop前端框架入门教程详解
2016/12/25 Javascript
基于vue实现swipe分页组件实例
2017/05/25 Javascript
原生JavaScript实现Ajax异步请求
2017/11/19 Javascript
Vue Socket.io源码解读
2018/02/07 Javascript
Vue表单类的父子组件数据传递示例
2018/05/03 Javascript
Vue.js实现数据响应的方法
2018/08/13 Javascript
js如何获取图片url的Blob值并预览示例代码
2019/03/07 Javascript
vue+elementUI动态增加表单项并添加验证的代码详解
2020/12/17 Vue.js
[01:22:29]真视界:2019年国际邀请赛总决赛
2020/01/29 DOTA
python修改txt文件中的某一项方法
2018/12/29 Python
python3 字符串/列表/元组(str/list/tuple)相互转换方法及join()函数的使用
2019/04/03 Python
Python+redis通过限流保护高并发系统
2020/04/15 Python
Pretty Little Thing爱尔兰:时尚女性服饰
2017/03/27 全球购物
金牌葡萄酒俱乐部:Gold Medal Wine Club
2017/11/02 全球购物
应届大学毕业生找工作的求职信范文
2013/11/29 职场文书
工作态度不端正检讨书
2014/10/04 职场文书
2014年安全工作总结范文
2014/11/13 职场文书
迎新生晚会主持词
2015/06/30 职场文书
运动会开幕式通讯稿
2015/07/18 职场文书
培训心得体会怎么写
2016/01/25 职场文书
2016年公共机构节能宣传周活动总结
2016/04/05 职场文书
导游词之蜀山胜景瓦屋山
2019/11/29 职场文书
将Python代码打包成.exe可执行文件的完整步骤
2021/05/12 Python