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 相关文章推荐
优秀js开源框架-jQuery使用手册(1)
Mar 10 Javascript
javascript IFrame 强制刷新代码
Jul 23 Javascript
javascript for循环设法提高性能
Feb 24 Javascript
jQuery实现动画效果的实例代码
May 07 Javascript
JS批量操作CSS属性详细解析
Dec 16 Javascript
解决angular的$http.post()提交数据时后台接收不到参数值问题的方法
Dec 10 Javascript
js 获取范围内的随机数实例代码
Aug 02 Javascript
JS函数修改html的元素内容,及修改属性内容的方法
Oct 28 Javascript
jQuery Easyui datagrid行内实现【添加】、【编辑】、【上移】、【下移】
Dec 19 Javascript
jQuery中layer分页器的使用
Mar 13 Javascript
Vue2.0+ElementUI实现表格翻页的实例
Oct 23 Javascript
thinkjs微信中控之微信鉴权登陆的实现代码
Aug 08 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数组实现无限分类,不使用数据库,不使用递归.
2006/12/09 PHP
PHP中集成PayPal标准支付的实现方法分享
2012/02/06 PHP
几道坑人的PHP面试题 试试看看你会不会也中招
2014/08/19 PHP
destoon文章模块调用企业会员资料的方法
2014/08/22 PHP
PHP防止注入攻击实例分析
2014/11/03 PHP
php自动载入类用法实例分析
2016/06/24 PHP
php.ini中date.timezone设置详解
2016/11/20 PHP
php常用字符函数实例小结
2016/12/29 PHP
javascript编程起步(第四课)
2007/01/10 Javascript
jQuery AJAX 调用WebService实现代码
2010/03/24 Javascript
jquery通过visible来判断标签是否显示或隐藏
2014/05/08 Javascript
node.js操作mongoDB数据库示例分享
2014/11/26 Javascript
jquery使用Cookie和JSON记录用户最近浏览历史
2016/04/19 Javascript
javascript深拷贝(deepClone)详解
2016/08/24 Javascript
Javascript之面向对象--接口
2016/12/02 Javascript
15个非常实用的JavaScript代码片段
2016/12/18 Javascript
浅谈javascript的url参数parse和build函数
2017/03/04 Javascript
vue2.0嵌套路由实现豆瓣电影分页功能(附demo)
2017/03/13 Javascript
js实现多行文本框统计剩余字数功能
2017/03/28 Javascript
AngularJS中重新加载当前路由页面的方法
2018/03/09 Javascript
微信小程序之导航滑块视图容器功能的实现代码(简单两步)
2020/06/19 Javascript
JavaScript中Object、map、weakmap的区别分析
2020/12/15 Javascript
天翼开放平台免费短信验证码接口使用实例
2013/12/18 Python
python基于ID3思想的决策树
2018/01/03 Python
pycharm 配置远程解释器的方法
2018/10/28 Python
完美解决Python matplotlib绘图时汉字显示不正常的问题
2019/01/29 Python
详解django2中关于时间处理策略
2019/03/06 Python
Python中函数的基本定义与调用及内置函数详解
2019/05/13 Python
python实战串口助手_解决8串口多个发送的问题
2019/06/12 Python
PyQt 实现使窗口中的元素跟随窗口大小的变化而变化
2019/06/18 Python
微信公众号token验证失败解决方案
2019/07/22 Python
HTML5实现晶莹剔透的雨滴特效
2014/05/14 HTML / CSS
北美最大的参茸药食商城:德成行
2020/12/06 全球购物
党支部培养考察意见
2015/06/02 职场文书
机械原理课程设计心得体会
2016/01/15 职场文书
Python Django 后台管理之后台模型属性详解
2021/04/25 Python