分享
 
 
 

&#106avascript面向对象的支持(2)

王朝html/css/js·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

================================================================================

Qomolangma OpenProject v0.9

类别 :Rich Web Client

关键词 :JS OOP,JS Framwork, Rich Web Client,RIA,Web Component,

DOM,DTHML,CSS,JavaScript,JScript

项目发起:aimingoo (aim@263.net)

项目团队:aimingoo, leon(pfzhou@gmail.com)

有贡献者:JingYu(zjy@cnpack.org)

================================================================================

2). 反射机制在JavaScript中的实现

------

JavaScript中通过for..in语法来实现了反射机制。但是JavaScript中并不

明确区分“属性”与“方法”,以及“事件”。因此,对属性的类型考查在JS

中是个问题。下面的代码简单示例for..in的使用与属性识别:

//---------------------------------------------------------

// JavaScript中for..in的使用和属性识别

//---------------------------------------------------------

var _r_event = _r_event = /^[Oo]n.*/;

var colorSetting = {

method: 'red',

event: 'blue',

property: ''

}

var obj2 = {

a_method : function() {},

a_property: 1,

onclick: undefined

}

function propertyKind(obj, p) {

return (_r_event.test(p) && (obj[p]==undefined || typeof(obj[p])=='function')) ? 'event'

: (typeof(obj[p])=='function') ? 'method'

: 'property';

}

var objectArr = ['window', 'obj2'];

for (var i=0; i<objectArr.length; i++) {

document.writeln('<p>for ', objectArr[i], '<hr>');

var obj = eval(objectArr[i]);

for (var p in obj) {

var kind = propertyKind(obj, p);

document.writeln('obj.', p, ' is a ', kind.fontcolor(colorSetting[kind]), ': ', obj[p], '<br>');

}

document.writeln('</p>');

}

一个常常被开发者忽略的事实是:JavaScript本身是没有事件(Event)系统的。通常我们在JavaScript用到的onclick等事件,其实是IE的DOM模型提供的。从更内核的角度上讲:IE通过COM的接口属性公布了一组事件接口给DOM。

有两个原因,使得在JS中不能很好的识别“一个属性是不是事件”:

- COM接口中本身只有方法,属性与事件,都是通过一组get/set方法来公布的。

- JavaScript中,本身并没有独立的“事件”机制。

因此我们看到event的识别方法,是检测属性名是否是以'on'字符串开头(以'On'开头的是Qomo的约定)。接下来,由于DOM对象中的事件是可以不指定处理函数的,这种情况下事件句柄为null值(Qomo采用相同的约定);在另外的一些情况下,用户可能象obj2这样,定义一个值为 undefined的事件。因此“事件”的判定条件被处理成一个复杂的表达式:

("属性以on/On开头" && ("值为null/undefined" || "类型为function"))

另外,从上面的这段代码的运行结果来看。对DOM对象使用for..in,是不能列举出对象方法来的。

最后说明一点。事实上,在很多语言的实现中,“事件”都不是“面向对象”的语言特性,而是由具体的编程模型来提供的。例如Delphi中的事件驱动机制,是由Win32操作系统中的窗口消息机制来提供,或者由用户代码在Component/Class中主动调用事件处理函数来实现。

“事件”是一个“如何驱动编程模型”的机制/问题,而不是语言本身的问题。然而以PME(property/method/event)为框架的OOP概念,已经深入人心,所以当编程语言或系统表现出这些特性来的时候,就已经没人关心“event究竟是谁实现”的了。

3). this与with关键字的使用

------

在JavaScript的对象系统中,this关键字用在两种地方:

- 在构造器函数中,指代新创建的对象实例

- 在对象的方法被调用时,指代调用该方法的对象实例

如果一个函数被作为普通函数(而不是对象方法)调用,那么在函数中的this关键字将指向window对象。与此相同的,如果this关键字不在任何函数中,那么他也指向window对象。

由于在JavaScript中不明确区分函数与方法。因此有些代码看起来很奇怪:

//---------------------------------------------------------

// 函数的几种可能调用形式

//---------------------------------------------------------

function foo() {

// 下面的this指代调用该方法的对象实例

if (this===window) {

document.write('call a function.', '<BR>');

}

else {

document.write('call a method, by object: ', this.name, '<BR>');

}

}

function MyObject(name) {

// 下面的this指代new关键字新创建实例

this.name = name;

this.foo = foo;

}

var obj1 = new MyObject('obj1');

var obj2 = new MyObject('obj2');

// 测试1: 作为函数调用

foo();

// 测试2: 作为对象方法的调用

obj1.foo();

obj2.foo();

// 测试3: 将函数作为“指定对象的”方法调用

foo.call(obj1);

foo.apply(obj2);

在上面的代码里,obj1/obj2对foo()的调用是很普通的调用方法。——也就是在构造器上,将一个函数指定为对象的方法。

而测试3中的call()与apply()就比较特殊。

在这个测试中,foo()仍然作为普通函数来调用,只是JavaScript的语言特性允许在call()/apply()时,传入一个对象实例来指定foo()的上下文环境中所出现的this关键字的引用。——需要注意的是,此时的foo()仍旧是一个普通函数调用,而不是对象方法调用。

与this“指示调用该方法的对象实例”有些类同的,with()语法也用于限定“在一段代码片段中默认使用对象实例”。——如果不使用with()语法,那么这段代码将受到更外层with()语句的影响;如果没有更外层的with(),那么这段代码的“默认使用的对象实例”将是window。

然而需要注意的是this与with关键字不是互为影响的。如下面的代码:

//---------------------------------------------------------

// 测试: this与with关键字不是互为影响的

//---------------------------------------------------------

function test() {

with (obj2) {

this.value = 8;

}

}

var obj2 = new Object();

obj2.value = 10;

test();

document.writeln('obj2.value: ', obj2.value, '<br>');

document.writeln('window.value: ', window.value, '<br>');

你不能指望这样的代码在调用结束后,会使obj2.value属性置值为8。这几行代码的结果是:window对象多了一个value属性,并且值为8。

with(obj){...}这个语法,只能限定对obj的既有属性的读取,而不能主动的声明它。一旦with()里的对象没有指定的属性,或者with()限定了一个不是对象的数据,那么结果会产生一个异常。

4). 使用in关键字的运算

------

除了用for..in来反射对象的成员信息之外,JavaScript中也允许直接用in关键字去检测对象是否有指定名字的属性。

in关键字经常被提及的原因并不是它检测属性是否存在的能力,因此在早期的代码中,很多可喜欢用“if (!obj.propName) {}” 这样的方式来检测propName是否是有效的属性。——很多时候,检测有效性比检测“是否存有该属性”更有实用性。因此这种情况下,in只是一个可选的、官方的方案。

in关键字的重要应用是高速字符串检索。尤其是在只需要判定“字符串是否存在”的情况下。例如10万个字符串,如果存储在数组中,那么检索效率将会极差。

//---------------------------------------------------------

// 使用对象来检索

//---------------------------------------------------------

function arrayToObject(arr) {

for (var obj=new Object(), i=0, imax=arr.length; i<imax; i++) {

obj[arr[i]]=null;

}

return obj;

}

var

arr = ['abc', 'def', 'ghi']; // more and more...

obj = arrayToObject(arr);

function valueInArray(v) {

for (var i=0, imax=arr.length; i<imax; i++) {

if (arr[i]==v) return true;

}

return false;

}

function valueInObject(v) {

return v in obj;

}

这种使用关键字in的方法,也存在一些限制。例如只能查找字符串,而数组元素可以是任意值。另外,arrayToObject()也存在一些开销,这使得它不适合于频繁变动的查找集。最后,(我想你可能已经注意到了)使用对象来查找的时候并不能准确定位到查找数据,而数组中可以指向结果的下标。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有