JavaScript 继承机制的实现(待续)


Posted in Javascript onMay 18, 2010

1.对象冒充
原理:构造函数使用this关键字给所有属性和方法赋值(即采用类声明的构造函数方式)。
因为构造函数只是一个函数,所以可使ClassA的构造函数成为ClassB的方法,然后调用它。ClassB就会收到ClassA的构造函数中定义的属性和方法。
例如:
下面方式定义的ClassA和ClassB:

function ClassA(sColor){ 
this.color=sColor; 
this.sayColor=function(){ 
alert(this.color); 
}; 
} function ClassB(sColor){ 
}

关键字this引用的是构造函数当前创建的对象。
不过在这个方法中国,this指向的是所属的对象。这个原理把ClassA作为常规函数来建立继承机制,而不是作为构造行数。
如下使用构造函数ClassB可以实现继承机制:
function ClassB(sColor){ 
this.newMethod=ClassA; 
this.newMethod(sColor); 
delete this.newMethod; 
}

这段代码中,为(但我觉得这里应该是"把")ClassA赋予了方法newMethod(记住函数名只是指向它的指针)。然后调用该方法,传递给它的是ClassB的构造函数的参数sColor。最后一行代码删除了对ClassA的引用,这样以后就不能再调用它。
所有的新属性和新方法都必须删除了新方法的代码行后定义。否则,可能会覆盖超类的相关属性和方法:
function ClassB(sColor,sName){ 
this.newMethod=classA; 
this.newMethod(sColor); 
delete this.newMethod; this.name=sName; 
this.sayName=function(){ 
alert(this.name); 
}; 
}

运行下面的例子:
var objA=new ClassA("red"); 
var objB=new ClassB("blue","Nicholas"); 
objA.sayColor();//outputs "red" 
objB.sayColor();//outputs "blue" 
objB.sayName(); //outputs "Nicholas"

例如,如果存在两个类ClassX和ClassY,ClassZ想继承这两个类,可以使用下面的代码:
function ClassZ(){ 
this.newMethod=ClassX; 
this.newMethod(); 
delete this.newMethod; this.newMethod=ClassY; 
this.newMethod(); 
delete this.newMethod; 
}

这里存在一个弊端,如果ClassX和ClassY具有同名的属性或方法,ClassY具有高优先级,因为它从后面继承。除了这一点小问题外,用对象冒充实现多继承机制轻而易举。
由于这种继承方式的流行,ECMAScript的第三版为Function对象加入了两个新方法,即call()和apply()。
2.call()方法
call()方法与经典的对象冒充方法最相似的方法。它的第一个参数用作this的对象。其他参数都直接传递给函数自身。例如:
function sayColor(sPrefix,sSuffix){ 
alert(sPrefix+this.color+sSuffix); 
}; 
var obj=new Object(); 
obj.color="red"; 
//outputs "The color is red,a very nice color indeed." 
sayColor.call(obj,"The color is ",", a very nice color indeed.")

在这个例子中,函数sayColor()在对象外定义,即使它不属于任何对象,也可以引用关键字this。对象的obj的color属性等于"red"。调用call()方法时,第一个参数是obj,说明
应该赋予sayColor()函数中的this关键字的值是obj。第二个和第三个参数是字符串。它们与sayColor()函数中的参数prefix和suffix匹配,最后生成消息"The color is red, a very nice color indeed."
要与继承机制的对象冒充方法一起使用该方法,只需将前三行的赋值、调用和删除代码替换即可:
function ClassB(sColor,sName){ 
//this.newMethod=classA; 
//this.newMethod(sColor); 
//delete this.newMethod; 
Class.call(this,sColor); this.name=sName; 
this.sayName=function(){ 
alert(this.name); 
}; 
}

这里,想让ClassA中的关键字this等于新创建的ClassB对象,因此this是第一个参数。第二个参数sColor对两个类来说都是唯一的参数。
3.apply()方法
apply()方法有两个参数,用作this的对象和要传递给函数的参数和数组。例如:
function sayColor(sPrefix,sSuffix){ 
alert(sPrefix+this.color+sSuffix); 
}; 
var obj=new Object(); 
obj.color="red"; //outputs "The Color is red,a very nice color indeed." 
sayColor.apply(obj,new Array("The Color is ",",a very nice color indeed."));

这个例子与前面的例子相同,只是现在调用的是apply()方法。调用apply()方法时,第一个参数仍是obj,说明应该赋予sayColor()中的this关键字值是obj。第二个参数是由两个字符串组成的数组,与sayColor()的参数prefix和suffix匹配。生成的消息仍是
"The Color is red,a nice color indeed."
该方法也用于替换前三行的赋值、调用和删除新方法的代码:
function ClassB(sColor,sName){ //this.newMethod=classA; 
//this.newMethod(sColor); 
//delete this.newMethod; 
ClassA.apply(this,new Array(sColor)); 
this.name=sName; 
this.sayName=function(){ 
alert(this.name); 
}; 
}

同样的,第一个参数仍是this。第二个参数是只有一个值color的数组。可以把ClassB的整个arguments对象作为第二个参数传递给apply()方法:
function ClassB(sColor,sName){ //this.newMethod=classA; 
//this.newMethod(sColor); 
//delete this.newMethod; 
ClassA.apply(this,arguments); 
this.name=sName; 
this.sayName=function(){ 
alert(this.name); 
}; 
}

当然,只有超类中的参数顺序与子类中的参数顺序完全一致时才可以传递参数对象。如果不是,就必须创建一个单独的数组,按照正确的顺序放置参数。此外,还可以使用call()方法。
Javascript 相关文章推荐
再谈IE中Flash控件的自动激活 ObjectWrap
Mar 09 Javascript
jQuery实现HTML表格单元格的合并功能
Apr 06 Javascript
Vue.js每天必学之指令系统与自定义指令
Sep 07 Javascript
BootStrap学习系列之布局组件(下拉,按钮组[toolbar],上拉)
Jan 03 Javascript
jQuery表格的维护和删除操作
Feb 03 Javascript
全面解析Node.js 8 重要功能和修复
Jun 02 Javascript
jQuery动态添加.active 实现导航效果代码思路详解
Aug 29 jQuery
解决vue组件中使用v-for出现告警问题及v for指令介绍
Nov 11 Javascript
JS动态插入脚本和插入引用外部链接脚本的方法
May 21 Javascript
vue多层嵌套路由实例分析
Mar 19 Javascript
vue使用axios上传文件(FormData)的方法
Apr 14 Javascript
浅谈Vue3 Composition API如何替换Vue Mixins
Apr 29 Javascript
JavaScript 面向对象编程(2) 定义类
May 18 #Javascript
JavaScript 面向对象编程(1) 基础
May 18 #Javascript
Javascript Object.extend
May 18 #Javascript
Jsonp 跨域的原理以及Jquery的解决方案
May 18 #Javascript
javascript 密码强度验证规则、打分、验证(给出前端代码,后端代码可根据强度规则翻译)
May 18 #Javascript
JS request函数 用来获取url参数
May 17 #Javascript
asp.net+js 实现无刷新上传解析csv文件的代码
May 17 #Javascript
You might like
PHP 加密/解密函数 dencrypt(动态密文,带压缩功能,支持中文)
2009/01/30 PHP
fleaphp常用方法分页之Pager使用方法
2011/04/23 PHP
PHP+Ajax实现的博客文章添加类别功能示例
2018/03/29 PHP
Hutia 的 JS 代码集
2006/10/24 Javascript
jQuery 方法大全方便学习参考
2010/02/25 Javascript
javascrip关于继承的小例子
2013/05/10 Javascript
jQuery Validate插件实现表单强大的验证功能
2015/12/18 Javascript
jQueryeasyui 中如何使用datetimebox 取两个日期间相隔的天数
2017/06/13 jQuery
基于Node.js模板引擎教程-jade速学与实战1
2017/09/17 Javascript
vue、react等单页面项目部署到服务器的方法及vue和react的区别
2018/09/29 Javascript
Nodejs处理异常操作示例
2018/12/25 NodeJs
Vue 理解之白话 getter/setter详解
2019/04/16 Javascript
详解小程序云开发攻略(解决最棘手的问题)
2019/09/30 Javascript
vue 弹出遮罩层样式实例
2020/07/22 Javascript
vue使用vue-quill-editor富文本编辑器且将图片上传到服务器的功能
2021/01/13 Vue.js
python在windows下创建隐藏窗口子进程的方法
2015/06/04 Python
Python 实现 贪吃蛇大作战 代码分享
2016/09/07 Python
python 定时器,轮询定时器的实例
2019/02/20 Python
python 叠加等边三角形的绘制的实现
2019/08/14 Python
Python提取PDF内容的方法(文本、图像、线条等)
2019/09/25 Python
python yield关键词案例测试
2019/10/15 Python
浅谈python之自动化运维(Paramiko)
2020/01/31 Python
Python使用pickle进行序列化和反序列化的示例代码
2020/09/22 Python
美国最大的高尔夫发球时间预订网站:TeeOff.com
2018/03/28 全球购物
CK巴西官方网站:Calvin Klein巴西
2019/07/19 全球购物
澳洲的UGG雪地靴超级市场:Uggs.com.au
2020/04/06 全球购物
在求职信中如何凸显个人优势
2013/10/30 职场文书
告诉你怎样写创业计划书
2014/01/27 职场文书
教育基金募捐倡议书
2014/05/14 职场文书
个人违纪检讨书
2014/09/15 职场文书
庆祝儿童节标语
2014/10/09 职场文书
党员群众路线教育实践活动剖析材料
2014/10/10 职场文书
离职报告格式
2014/11/04 职场文书
浅谈什么是SpringBoot异常处理自动配置的原理
2021/06/21 Java/Android
vue选项卡切换的实现案例
2022/04/11 Vue.js
图神经网络GNN算法
2022/05/11 Python