网络编程
位置:首页>> 网络编程>> JavaScript>> 如何判断JavaScript变量的类型(2)

如何判断JavaScript变量的类型(2)

作者:明达 来源:七月佑安 发布时间:2009-02-25 12:28:00 

标签:JavaScript,变量,类型,脚本

基本上完结了,我们还是没有彻底的消除object,一个典型的情况就是通过{}直接定义对象,那个名字我是不会获取了,谁要是知道一定要告诉我。再比较特殊的就是IE了,有N多对象无法判断实际类型,只能给出object,暂时没有头绪。

2月7日更新,发现原来的代码还是存在很多漏洞的,更新了一下,并转换为jQuery插件:

/*
(function($){
$.extend({
tof: function(val, description) {
       var result, constructorName;
       switch(val) {
           case null: result = "Null"; break;
           case undefined: result = "Undefined"; break;
           default:
               result = Object.prototype.toString.call(val).match(/^\[object\s(\w+)\]$/)[1];
           
               if(typeof(Node) !== "undefined") {
                   if(val instanceof Node) {
                       if(typeof(val.nodeName) === "string") {
                           result = val.nodeName;
                       }
                   }
               }
               else {
                   if(typeof(val.nodeName) === "string") {
                       result = val.nodeName;
                   }
               }

               if(result === "Object") {
                   // can not access fireunit's constructor
                   try {
                       if(typeof(val.constructor) !== "undefined") {
                           constructorName = val.constructor.toString().match(/^\s*function\s(\w+)/);
                           if(constructorName !== null) {
                               result = constructorName[1];
                           }
                       }
                   } catch(err) {}
               }
               break;
       }
       return  result.toLowerCase();
}
});
})(jQuery);
*/

这里需要提一下的是,在IE中,无论怎么判断,alert、confirm和prompt三个函数的类型都是object,而在其他所有浏览器中都是function。

在玉伯那里,有一个这样的例子,经过测试是可以判断出数组的:

/*
function SubArray() {}
SubArray.prototype = [];
jstest.add(new SubArray(), "array", "prototype is array");
*/

对于数值来说,通过字面量定义的肯定返回number,而对于用new Number来定义的,虽然typeof的值是object,其实使用的过程中都会自动调用valueOf,所以在这里也会返回number的。而对于那些定义在全局变量上,和数值相关的特殊属性,获取类型也是number:

/*
jstest.add(0, "number", "literal number 0");
jstest.add(1, "number", "literal number 1");
jstest.add("1", "string", "string \"1\"");
jstest.add(new Number(1.5), "number", "new Number(1.5)");
jstest.add((new Number(1.5)).valueOf(), "number", "(new Number(1.5)).valueOf()");
jstest.add((new Number(1.5)).toString(), "string", "(new Number(1.5)).toString()");
jstest.add(NaN, "number", "NaN - not a number");
jstest.add(Infinity, "number", "Infinity");
jstest.add(-Infinity, "number", "-Infinity");
*/

和布尔值相关的测试用例:

/*
jstest.add(true, "boolean", "literal boolean true");
jstest.add(false, "boolean", "literal boolean false");
jstest.add(new Boolean(true), "boolean", "new Boolean(true)");
*/

和浏览器的内置对象相关的测试用例:

/*
jstest.add(new Error(), "error", "new Error()");
jstest.add(new EvalError(), "error", "new EvalError()");
jstest.add(new Date(), "date", "new Date()");
jstest.add(/abc/, "regexp", "literal regular expression");
jstest.add(new RegExp("a?"), "regexp", "new RegExp()");
jstest.add([], "array", "array by []");
jstest.add(new Array(), "array", "array by new Array()");
jstest.add(Math, "math", "Math");
*/

DOM对象的测试用例:

/*
jstest.add(document.createElement("div"), "div", "HTML Element");
jstest.add(document, "#document", "document");
*/

自定义对象的测试用例:

/*
function TestClass(){};
jstest.add(new TestClass(), "testclass", "custom object, new TestClass()");
*/


2009年2月10日更新,上面的测试用例,测试的内容没有变,但已经单独提出来了,这两天整理出一篇来。

测试环境:
* Firefox 3.0.6
* Internet Explorer 7.0
* Safari 3.2
* Opera 9.63
* Chrome 1.0.154.48

参考资料:
* http://lucassmith.name/pub/typeof.html
* http://blog.360.yahoo.com/blog-TBPekxc1dLNy5DOloPfzVvFIVOWMB0li?p=916
* http://lifesinger.org/blog/?p=1109
* http://lifesinger.org/blog/?p=1130
* http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html

写在最最后面的
现在的状态应该说只能算是第一个版本吧,应该还有很大的优化余地,最终的目标应该是一个非常增强的typeof,不止要能适应各个浏览器的各个版本,还要尽可能多的判断出各种对象。大家要有好的改进想法,记得告诉我哟。

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com