如何判断JavaScript变量的类型
作者:明达 来源:七月佑安 发布时间:2009-02-25 12:28:00
数据类型是所有开发语言的基础,JavaScript虽然是一个弱类型的脚本语言,但是在数据类型上也有很多讲究的,看了淘宝UED玉伯的一篇文章,末尾有一个判断数据类型的函数,仔细揣摩后发现有一些改进的余地,于是有了本文。目标就是一个可以提供足够类型参考信息的函数。
【测试地址1】http://lab.cuimingda.com/jquery/tof/
【测试地址2】http://lab.cuimingda.com/detection/window.html
在JavaScript中,变量中可以存储的值主要有两种类型:原始值(primitive value)和引用值(reference value)。前者通常是固定而又简单的数据,存储在栈(stack)中,而后者则是比较大的对象,存储在堆(heap)中,而对于后者的调用,是通过存储在栈中的指针来完成的。原始类型有五种:Number、String、Boolean、Null和Undefined,引用类型都继承自Object。
我们的最终目标就是一个叫做tof的全局函数,返回值为字符串,代表anything对应的类型,因为所有的引用类型都是object,所以这里返回的类型应该不局限于数据类型,应该尽可能的反映出anything的真实信息:
/*
var t = tof(anything);
*/
第一个实现肯定是利用传统的typeof来实现:
/*
function tof(val) {
return typeof(val);
}
*/
typeof可以得出的结论有五种:undefined、string、number、boolean和object。和原始类型比较还差个null,这个比较特殊,typeof(null)的返回值是object,这本来是JavaScript早期的bug,但后来却被写入了ECMAScript标准,可以理解为null是object的占位符。很明显,typeof无法满足我们的需求。
幸好Google的Mark Miller找到另外一个非常有效的判断数据类型的方法,就是利用Object.prototype.toString.call,用这个方法对Date类型数据进行计算,得到的结果是“[object Date]”,对于其他类型,前半部分始终是object,后半部分会发生变化,这样就很方便我们判断了。jQuery从1.3开始,也采用了这种方法判断array和function。下面我们来改进一下:
/*
function tof(val) {
return Object.prototype.toString.call(val).match(/object\s(\w+)/)[1];
}
*/
这个函数现在已经可以判断非常多的情况了,等等,undefined和null怎么返回的是Window(Firefox 3.0.6和Opera 9.63),在IE 7下返回Object,在Chrome返回builtins,在Safari 3.2下返回DOMWindow,明显优于这两个被定义为全局对象的属性,在不同的浏览器下挂到了不同的全局对象上。既然这么特殊,只能对他们单独有待一下了:
/*
function tof(val) {
var t;
switch(val) {
case null: t = "null"; break;
case undefined: t = "undefined"; break;
default:
t = Object.prototype.toString.call(val).match(/object\s(\w+)/)[1];
break;
}
return t.toLowerCase();
}
*/
到这里,我们已经可以判断很多object了,包括array、regexp、date等。让我们再多想一些,比如你碰到过需要判断DOM元素类型的情况么?这个首先要说明个问题,我们访问DOM,其实有两种方式,一种是通过树型的继承方式,就是Element为基础的,另外一种是构建在xml基础上的node模式,而对应每个节点都有tagName和nodeName两个属性,大部分时候要求是必须一样的,一些特殊节点只有nodeName,没有tagName,比如document的nodeName为“#document”,tagName为空值。
/*
function tof(val) {
var t;
switch(val) {
case null: t = "null"; break;
case undefined: t = "undefined"; break;
default:
t = val.nodeName || Object.prototype.toString.call(val).match(/object\s(\w+)/)[1];
break;
}
return t.toLowerCase();
}
*/
如果是DOM元素,首先取节点名称,取不到再用老办法判断对象类型。这样,不管是通过document.createElement构建的元素,还是通过document.getElementById获取的元素,都可以得到一个可以参考的类型了,注意此类型非彼类型,只是元素名称而已。经过了以上几个步骤,还有什么情况会出现object呢,其中一个就是我们自己定义的对象,或者称为类?这里我们采用构造函数来搞定。
/*
function tof(val) {
var t;
switch(val) {
case null: t = "null"; break;
case undefined: t = "undefined"; break;
default:
t = val.nodeName || Object.prototype.toString.call(val).match(/object\s(\w+)/)[1];
if(!!val.constructor && t.toLowerCase() === "object") {
t = val.constructor.toString().match(/^\s*function\s(\w+)/)[1];
}
break;
}
return t.toLowerCase();
}
*/
构造函数的判断放到最后,不得已而为之的情况。一是要处理那些还处于object状态的,二是要确保人家要有构造函数,可不是每个对象都有构造函数的。构造函数的类型是function,如果直接拿来比较在有些时候会有问题,比如不同框架的时候。所以我们将function的内容转换为字符串,通过正则表达式来取函数名。这里有个插曲就是,IE很缺德,在function前面加了一个空格,害我多调了好半天正则表达式。
猜你喜欢
- 如何用METADATA替换ADOVBS.INC? 在ASP中,使用组件时,如ADO,得先包含
- 随机背景--当你每次进入该页面时,从已指定的图片文件夹中,随机选取一个图片作为背景显示。这里介绍的方法是用ASP+CSS来实现的。 &nbs
- 如果在 Access 数据库中删除数据或对象,或者在 Access 项目中删除对象,Access 数据库或 Access 项目可能会产生碎片
- 有些使用Z-Blog的用户询问我,怎么实现我的月光博客首页上这种自动图文混排的版式效果,今天我就详细介绍一下在Z-Blog中实现这种图文混排
- 介绍:细处着手,巧处用功。高手和菜鸟之间的差别就是:高手什么都知道,菜鸟知道一些。电脑小技巧收集最新奇招高招,让你轻松踏上高手之路。 摘 要
- 原文地址:30 Days of Mootools 1.2 Tutorials - Day 2 - Selectors如果你还没有准备好,请先
- 注:文中未表明的地方output 输出都是基于IE6.0,其中表明FF的地方为Mozilla Firefox2.0,还要注意文中的大小写ja
- jQuery是一个非常优秀的JavaScript 框架,使用简单灵活,同时还有许多成熟的插件可供选择,它可以帮助你在项目中加入一些非常好的效
- 130 :文件格式不正确。(还不是很清楚错误的状况) 145 :文件无法打开。 1005:创建表
- 如果直接执行SQL语句或者参数绑定则不用担心太多,如以下ORACLE存储过程 create or replace&nbs
- 在讨论IE6的BUG及如何修复之前,有必要讲叙一些策略去避免这些恼人的问题——正所谓防患于未然 。IE6 市场占有率据Market Shar
- 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的编写,刚开始不会体会出SQL语句各种写法的性能优劣,但是如果将应
- 安装时建议你为MySQL管理创建一个用户和组。由该组用户运行mysql服务器并执行管理任务。(也可以以root身份运行服务器,但是不推荐)第
- 做一个总结,把自己这些年的从业经历和观感罗列一下,某些话可能触及到个人神经,但它们没有恶意。设计师喜欢把世界想象得很美好,社会很和谐,但是这
- Tips 1:新增数据表与定义字段更加直观若要建立新数据表,可以在开启数据库后,直接单击“创建”标签,在“表”选项组中单击“表”按钮,即可新
- Set objTextStream=FileSystemObject.CreateTextFile(Filename,[Overwrite]
- 如何在ADO服务器端利用好缓存技术?请看下面示例,这是一个用来显示图书分类的例子程序:displayBooks.asp< %
- 作者的blog :http://www.planabc.net/老甘的《完全用CSS实现的中英文双语导航菜单》一文中使用“position:
- 很多人都有研究闭合浮动元素的问题,但是解决方法却不一样,也并不是每一种方法都尽善尽美。闭合浮动元素(或者叫清除浮动)是web标准设计中经常会
- 见下表:序号保留字序号保留字序号保留字1ADD80ESCAPE159OR2ABSOLUTE81EXCEPT160ORDER3ACTION82