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 相关文章推荐
javascript网页关闭时提醒效果脚本
Oct 22 Javascript
再谈javascript 动态添加样式规则 W3C校检
Dec 25 Javascript
javascript中最常用的继承模式 组合继承
Aug 12 Javascript
js实现简单随机抽奖的方法
Jan 27 Javascript
JavaScript希尔排序、快速排序、归并排序算法
May 08 Javascript
JS验证 只能输入小数点,数字,负数的实现方法
Oct 07 Javascript
JS实现图片高斯模糊切换效果的焦点图实例
Jan 21 Javascript
Vue如何引入远程JS文件
Apr 20 Javascript
js下拉菜单生成器dropMenu使用方法详解
Aug 01 Javascript
vue iview组件表格 render函数的使用方法详解
Mar 15 Javascript
vue动画效果实现方法示例
Mar 18 Javascript
JavaScript生成随机验证码代码实例
Sep 28 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
qq登录,新浪微博登录接口申请过程中遇到的问题
2014/07/22 PHP
PHP使用Mysqli类库实现完美分页效果的方法
2016/04/07 PHP
PHPStorm+XDebug进行调试图文教程
2016/06/13 PHP
php自定义函数br2nl实现将html中br换行符转换为文本输入中换行符的方法【与函数nl2br功能相反】
2017/02/17 PHP
php获取目录下所有文件及目录(多种方法)(推荐)
2019/05/14 PHP
Javascript实现的分页函数
2006/12/22 Javascript
表单项的name命名为submit、reset引起的问题
2007/12/22 Javascript
jQuery 下拉列表 二级联动插件分享
2012/03/29 Javascript
js实现身份证号码验证的简单实例
2014/02/19 Javascript
Jquery给基本控件的取值、赋值示例
2014/05/23 Javascript
jQuery实现带滚动线条导航效果的方法
2015/01/30 Javascript
JS实现的最简Table选项卡效果
2015/10/14 Javascript
javascript实现全角转半角的方法
2016/01/23 Javascript
Javascript中的getter和setter初识
2017/08/17 Javascript
详解nodejs中express搭建权限管理系统
2017/09/15 NodeJs
layui 选择列表,打勾,点击确定返回数据的例子
2019/09/02 Javascript
加速vue组件渲染之性能优化
2020/04/09 Javascript
[01:34]2014DOTA2展望TI 剑指西雅图VG战队专访
2014/06/30 DOTA
Python函数可变参数定义及其参数传递方式实例详解
2015/05/25 Python
python微元法计算函数曲线长度的方法
2018/11/08 Python
python3使用QQ邮箱发送邮件
2020/05/20 Python
浅谈pyqt5中信号与槽的认识
2019/02/17 Python
2019 Python最新面试题及答案16道题
2019/04/11 Python
Django之无名分组和有名分组的实现
2019/04/16 Python
PyQt5.6+pycharm配置以及pyinstaller生成exe(小白教程)
2020/06/02 Python
python海龟绘图之画国旗实例代码
2020/11/11 Python
pycharm中选中一个单词替换所有重复单词的实现方法
2020/11/17 Python
全网最详细的PyCharm+Anaconda的安装过程图解
2021/01/25 Python
CSS3实现淘宝留白的方法
2020/06/05 HTML / CSS
斯凯奇澳大利亚官网:SKECHERS澳大利亚
2018/03/31 全球购物
日语翻译个人求职的自我评价
2013/10/14 职场文书
计算机数据库专业职业生涯规划书
2014/02/08 职场文书
九一八事变演讲稿
2014/09/05 职场文书
2014年综治维稳工作总结
2014/11/17 职场文书
2020年基层司法所建设情况调研报告
2019/11/30 职场文书
MySQL update set 和 and的区别
2021/05/08 MySQL