如何判断JavaScript变量的类型(2)
作者:明达 来源:七月佑安 时间:2009-02-25 12:28:00
基本上完结了,我们还是没有彻底的消除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,不止要能适应各个浏览器的各个版本,还要尽可能多的判断出各种对象。大家要有好的改进想法,记得告诉我哟。