分享
 
 
 

javascript的“反射”机制

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

这里用“反射”这个词仅是一种概念上的借用,且不论下面提到的javascript的特性是否可以被称为“反射”,javascript这种获得对象类型(通过typeof运算)、构造函数(通过观察constructor属性)甚至枚举属性和方法的特性确实为我们学习、研究和使用javascript带来了极大的便利。

在javascript中可以利用for...in方法枚举出对象中所有“可列举”的属性和方法,包括通过prototype机制“继承”的属性和方法

例如:

function classA()

{

classA.prototype.a = function(){return "a";};

}

function classB()

{

classB.prototype.b = function(){return "b";};

}classB.prototype = new classA();

var msg = new Array();

var b = new classB();

for (idx in b)

{

msg.push(idx);

}

alert(msg);

上面这个例子列举出了classB的对象b的所有可列举属性和方法(不可列举的属性方法包括大多数javascript内置对象的固有方法,如Object.isPropertyOf等等,但html对象和dom对象的方法都是可列举的),包括a、b两个成员函数。另外由于javascript中通过关联数组引用和通过函数调用引用无参方法等效(即b["a"]和b.a()都返回字符串"a"),所以将上面例子的循环体改成msg.push(b[idx]);就可以遍历执行b中的所有方法并将结果返回给msg。

另外一个有趣的话题是关于instanceof运算的。javascript的instanceof运算足够强大,强大到支持“继承”的判别,如上面那个例子,b instance of classA和b instance of classB的结果都是true。instanceof运算的这个能力正是我们使用“多态”所需要的。

相反地,同强大的instanceof运算相比,javascript的typeof运算则显得有些简陋。它只能识别出string、number等基本类型和object与function类型。这样,要判断对象类型的话,typeof就无能为力。一个比较勉强的解决方案是依靠constructor属性来判断,但是,constructor有个很烦人的问题是,它默认返回的是prototype中的构造函数。结果上面的例子中对象b的constructor竟然返回classA,而不是令人期待的classB,于是,只好在每次继承之时手工修改constructor属性,上面的例子中在classB.prototype=new classA();之后添上classB.constructor = classB。

最后谈到dom对象的问题。在javascript中dom对象和普通对象可以通过判断tagName属性来区别,但是这不是非常好的办法,因为你很难禁止他人在普通对象中定义tagName属性。另外一个比较好的方法是dom对象的constructor属性一般为undefined(同时,显然地,instanceof Object将返回false,这是它们区别其他对象的一个明显特征,当然,前提是必须保证javascript的标准在将来不会扩充到给dom对象赋予确定的constructor和严格的继承机制!最后,我想要说的是,javascript的“反射机制”是强大的,但是也是不完善的,所以在使用的时候需要小心,“常识”往往也容易令人犯错。

结束话题之前发一个稍微封装的“反射”管理类,希望它能够给大家带来一些便利:

function Reflector()

{

Reflector.getType=function(obj)

{

if (obj == null) //null的类型

{

return null;

}

else if (obj instanceof Object) //普通对象

{

return obj.constructor;

}

else if (obj.tagName != null) //dom对象

{

return obj.tagName;

}

else

{

return typeof(obj);

}

}

Reflector.getAttributes=function(obj)

{

var methods = new Array();

for (idx in obj)

{

methods.push(new Type(obj[idx],ClassManager.getType(obj[idx]),idx));

}

return methods;

}

Reflector.getAttributeNames=function(obj)

{

var methods = new Array();

for (idx in obj)

{

methods.push(idx);

}

return methods;

}

}

//描述类型的类,entity是对象实体,type是对象类型,name是对象名称

function Type(entity, type, name)

{

this.Entity = entity;

this.Type = type;

this.Name = name;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有