如何判断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前面加了一个空格,害我多调了好半天正则表达式。
猜你喜欢
- 前言本篇给大家分享一下《通过Python的pdfplumber库将pdf转为图片》。一、pdfplumber库是什么?pdfplumber是
- 装饰器本质上是一个 Python 函数或类,它可以让其他函数或类在不需要做任何代码修改的前提下增加额外功能,装饰器的返回值也是一个函数/类对
- 在不使用matlab的情况下,可以选择用python来实现自动控制理论有关系统打时域分析和频率域分析等,安装的package是python-
- openpyxlopenpyxl是⼀个Python库,用于读取/写⼊Excel 2010 xlsx / xlsm / xltx / xltm
- 最近在做公司的某个从项目,基本设计和淘宝登陆页类似: 1)文本框内容为空是,文本框右侧无清除按钮,当有内容时立即显示清除按钮;2)当文本框失
- 前些日子在做绩效体系的时候,遇到了一件囧事,居然忘记怎样在Excel上拟合正态分布了,尽管在第二天重新拾起了Excel中那几个常见的函数和图
- 本文实例为大家分享了python放大图片和画方格的具体代码,供大家参考,具体内容如下1、Python 放大图片和画方格算法#!C:/Pyth
- (1)最近真是郁闷,在Myeclipse中使用DB Browser但出现以下问题:(2)然后赶紧百度,求大神解决,主要的解决方法试一下几种:
- 基准函数是测试演化计算算法性能的函数集,由于大部分基准函数集都是C/C++编写,Python编写的基准函数比较少,因此本文实现了13个常用基
- 在制作登录页面时学习了TK弹窗的输入文本框的使用,下面让我们一起来学习一下TK弹窗中的输入框及文本框的使用方法吧!输入框要想制作一个输入弹窗
- 在使用JavaScriptSerializer.Serialize 方法转json对象时,遇到一个问题,后台方法生成的json字符串中有没有
- 前言面对计算密集型的任务,除了多进程,就是分布式计算,如何用 Python 实现分布式计算呢?今天分享一个很简单的方法,那就是借助于 Ray
- 上期回顾上一次的图像清晰度评价没有成功,主要的原因是那几张图像清晰度评价函数都实际都采用了梯度求解,不同的场景灰度的明暗不同,梯度可能会很大
- 本文为大家分享了Python遗传算法解决最大流问题,供大家参考,具体内容如下Generate_matrixdef Generate_matr
- 一.图像阈值化图像阈值化(Binarization)旨在剔除掉图像中一些低于或高于一定值的像素,从而提取图像中的物体,将图像的背景和噪声区分
- 多页应用每一次页面跳转的时候,后台服务器都会给返回一个新的html文档,这种类型的网站也就是多页网站,也叫做多页应用。为什么多页应用的首屏时
- 具体方法:1使用panda read_excel 方法加载excel2使用concat将DataFrame列表进行拼接3然后使用pd.Exc
- 不管学习什么编程语言一开始都会经历的四步开发工具安装IDE安装设置 依赖/包 国内镜像项目构建工具,管理依赖/包一、Golang 开发工具安
- 导语:谷歌浏览器中有个很有名的彩蛋:当你网络出现问题时,就会出现一个“小恐龙游戏”。🦖相信很多人都玩过 chrome 上提供的恐龙跑跑游戏,
- 打印类的所有属性和方法利用dir(obj)方法获得obj对象的所有属性和方法名,返回一个list。for item in dir(top_k