Flyingis

Talking and thinking freely !
Flying in the world of GIS !
随笔 - 156, 文章 - 16, 评论 - 589, 引用 - 0
数据加载中……

JavaScript 对象的反射及应用

    作者:Flyingis

    Java和.NET都有着比较完善的反射机制,用来处理未知的对象并获取它们的属性和方法。JavaScript虽然没有完善的反射体系,但在编程的时候还是可以通过代码设计来实现类似反射的基本功能。

    检测一个JavaScript对象是否支持某种特定的属性或方法:

if (typeof(obj.property) != "undefined"{}

    这样声明比直接使用"if (obj.property)"来描述要更准确,因为当obj.property的值为false、0、null的时候,虽然该属性存在,但返回的结果却恰恰相反。

    如果要求检测更详细一些,查看该属性的具体类型,可以用instanceof操作符:

if (obj instanceof PredefinedObj) {}

    但是,当对obj对象进行条件检测的时候,如果多种条件的对象类型存在继承关系,则需要注意代码的书写顺序,例如:

function() ExamineType(obj) {
  
if (obj instanceof Object) {
    alert(
"An Object");
  
else if (obj instanceof Array) {
    alert(
"An Array");
  }

  }

}

    上述代码执行的结果会认为原为Array类型的obj是一个Object,因为Array本身就是从Object继承而来,显然,将对Array的检测放在前面会得到更精确的结果。因此,使用instanceof来判断对象类型,需要注意当两个对象存在继承关系的时候,应该关注检测顺序的问题,进一步我们可以想到,JSON创建的对象不是Object就是Array,使用instanceof来检测JSON对象意义不大。

    利用JavaScript的反射,我们可以编写一个函数来检查对象是否有一个特定名称的函数,然后利用该函数进行计算,以此在JavaScript中实现接口的功能,为在Ajax中使用设计模式奠定基础。

//this.getWeight和this["getWeight"]意义相同
//
判断对象是否存在指定名称的函数
Object.prototype.hasFunc = function(func) {
  
return this && this[func] && this[func] instanceof Function;
}


function hasWeight(obj) {
  
return obj.hasFunc("getWeight");
}


//判断参数是否为数值类型
function isNum(param) {
  
return parseFloat(param) != NaN;
}


//计算两个对象的重量
function calWeight(obj1, obj2) {
  
var total = null;
  
if (hasWeight(obj1) && hasWeight(obj2)) {
    
var w1 = obj1.getWeight();
    
var w2 = obj2.getWeight();
    
if (isNum(w1) && isNum(w2)) {
      total 
= parseFloat(w1) + parseFloat(w2);
    }

  }

  
return total;
}

    calWeight先判断两个对象是否均存在getWeight()函数,然后检查getWeight()计算结果是否为数值类型,最后进行数值相加返回计算结果。需要注意的是,parseFloat(param)函数能够除去param中非数字部分,如果param=16pm,parseFloat(16pm)得到的结果是16。如果不使用parseFloat(param)函数对getWeight()计算结果进行检验,那么会带来安全性的问题,这种情况下可以将对象的getWeight()设计为返回字符串或其他类型,在调用它之前我们是不知道JavaScript函数的返回类型的,因为JavaScript函数没有预先定义的类型。

posted on 2006-09-12 18:50 Flyingis 阅读(5264) 评论(5)  编辑  收藏 所属分类: Web 客户端技术

评论

# re: JavaScript 对象的反射及应用  回复  更多评论   


你好,有个疑问---
"parseFloat(param) != NaN"

可以直接这样比较吗? 好像要利用 isNaN()函数吧?
2006-09-19 18:37 | 飞飞

# re: JavaScript 对象的反射及应用  回复  更多评论   

@飞飞
NaN就是指not a number,可以用来直接和变量比较。isNaN()是判断函数,上面例子可以写成:
"parseFloat(param).isNaN() == false"。
2006-09-20 10:29 | Flyingis

# re: JavaScript 对象的反射及应用  回复  更多评论   

这就叫多此一举了,何不直接这样呢:
function isNum(param) {
return !isNaN(parseFloat(param));
}

顺便说一下,obj.property的值不但可以是null,false,0,也可以是undefined。这种情况下这个property也是存在的:
var o={};
o.a=undefined;
for(var i in o) alert(typeof(o[i])=="undefined")
2006-09-29 00:12 | emu

# re: JavaScript 对象的反射及应用[未登录]  回复  更多评论   

useless
2007-10-22 21:34 | aaa

# re: JavaScript 对象的反射及应用  回复  更多评论   

没用
2008-02-20 23:43 | 象的

只有注册用户登录后才能发表评论。


网站导航: