JavaScript isArray()函数判断对象类型的种种方法


Posted in Javascript onOctober 11, 2010

1) typeof 运算符
typeof 是一元运算符,返回结果是一个说明运算数类型的字符串。如:"number","string","boolean","object","function","undefined"(可用于判断变量是否存在)。
但 typeof 的能力有限,其对于Date、RegExp类型返回的都是"object"。如:

typeof {}; // "object" 
typeof []; // "object" 
typeof new Date(); // "object"

所以它只在区别对象和原始类型的时候才有用。要区一种对象类型和另一种对象类型,必须使用其他的方法。如:instanceof 运算符或对象的 constructor 属。

2)instanceof 运算符。
instanceof 运算符要求其左边的运算数是一个对象,右边的运算数是对象类的名字或构造函数。如果 object 是 class 或构造函数的实例,则 instanceof 运算符返回 true。如果 object 不是指定类或函数的实例,或者 object 为 null,则返回 false。如:

[] instanceof Array; // true
[] instanceof Object; // true
[] instanceof RegExp; // false
new Date instanceof Date; // true

所以,可以用instanceof运算符来判断对象是否为数组类型:

function isArray(arr)
{
return arr instanceof Array;
}

3)constructor 属性。
JavaScript中,每个对象都有一个constructor属性,它引用了初始化该对象的构造函数,常用于判断未知对象的类型。如给定一个求知的值通过typeof运算符来判断它是原始的值还是对象。如果是对象,就可以使用constructor属性来判断其类型。所以判断数组的函数也可以这样写:

function isArray(arr)
{
return typeof arr == "object" && arr.constructor == Array;
}

很多情况下,我们可以使用instanceof运算符或对象的constructor属性来检测对象是否为数组。例如很多JavaScript框架就是使用这两种方法来判断对象是否为数组类型。
但是检测在跨框架(cross-frame)页面中的数组时,会失败。原因就是在不同框架(iframe)中创建的数组不会相互共享其prototype属性。例如:

<script> 
window.onload=function(){ 
var iframe_arr=new window.frames[0].Array; 
alert(iframe_arr instanceof Array); // false 
alert(iframe_arr.constructor == Array); // false 
} 
</script> 
<body> 
<iframe></iframe> 
</body>

在Ajaxian上看到了一种精确的检测方法,跨原型链调用toString()方法:Object.prototype.toString()。可以解决上面的跨框架问题。

当Object.prototype.toString(o)执行后,会执行以下步骤:
1)获取对象o的class属性。
2)连接字符串:"[object "+结果(1)+"]"
3)返回 结果(2)

例如:

Object.prototype.toString.call([]); // 返回 "[object Array]"
Object.prototype.toString.call(/reg/ig); // 返回 "[object RegExp]"

这样,我们就可以写一个健壮的判断对象是否为数组的函数:

function isArray(arr) 
{ 
return Object.prototype.toString.call(arr) === "[object Array]"; 
}

此种方法得到国外多个javaScript大师的认可,在即将发布的jQuery 1.3中将使用这种方法来检测数组。

prototype.js的一个维护者写了下面这个函数,用于获取对象的类型名

/** 
* Returns internal [[Class]] property of an object 
* 
* Ecma-262, 15.2.4.2 
* Object.prototype.toString( ) 
* 
* When the toString method is called, the following steps are taken: 
* 1. Get the [[Class]] property of this object. 
* 2. Compute a string value by concatenating the three strings "[object ", Result (1), and "]". 
* 3. Return Result (2). 
* 
* __getClass(5); // => "Number" 
* __getClass({}); // => "Object" 
* __getClass(/foo/); // => "RegExp" 
* __getClass(''); // => "String" 
* __getClass(true); // => "Boolean" 
* __getClass([]); // => "Array" 
* __getClass(undefined); // => "Window" 
* __getClass(Element); // => "Constructor" 
* 
*/ 
function __getClass(object) 
{ 
return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1]; 
};

扩展一下,用于检测各种对象类型:
var is = 
{ 
types : ["Array", "Boolean", "Date", "Number", "Object", "RegExp", "String", "Window", "HTMLDocument"] 
} for(var i = 0, c; c = is.types[i ++ ]; ) 
{ 
is[c] = (function(type) 
{ 
return function(obj) 
{ 
return Object.prototype.toString.call(obj) == "[object " + type + "]"; 
} 
} 
)(c); 
} 
alert(is.Array([])); // true 
alert(is.Date(new Date)); // true 
alert(is.RegExp(/reg/ig)); // true
Javascript 相关文章推荐
javascript while语句和do while语句的区别分析
Dec 08 Javascript
利用JS重写Cognos右键菜单的实现代码
Apr 11 Javascript
基于jQuery实现网页进度显示插件
Mar 04 Javascript
纯JavaScript实现的分页插件实例
Jul 14 Javascript
jQuery实现内容定时切换效果完整实例
Apr 06 Javascript
Boostrap入门准备之border box
May 09 Javascript
vue2.0嵌套路由实现豆瓣电影分页功能(附demo)
Mar 13 Javascript
webpack配置之后端渲染详解
Oct 26 Javascript
vue2单元测试环境搭建
May 24 Javascript
vue 移动端记录页面浏览位置的方法
Mar 11 Javascript
Js生成随机数/随机字符串的方法小结【5种方法】
May 27 Javascript
electron踩坑之dialog中的callback解决
Oct 06 Javascript
JSChart轻量级图形报表工具(内置函数中文参考)
Oct 11 #Javascript
jQuery 表单验证扩展代码(一)
Oct 11 #Javascript
AlertBox 弹出层信息提示框效果实现步骤
Oct 11 #Javascript
基于jQuery的实现简单的分页控件
Oct 10 #Javascript
JQuery的Alert消息框插件使用介绍
Oct 09 #Javascript
Tips 带三角可关闭的文字提示
Oct 06 #Javascript
从零开始学习jQuery (二) 万能的选择器
Oct 01 #Javascript
You might like
PHP操作MongoDB时的整数问题及对策说明
2011/05/02 PHP
PHP小教程之实现双向链表
2014/06/12 PHP
浅谈PHP解析URL函数parse_url和parse_str
2014/11/11 PHP
浅谈PHP安全防护之Web攻击
2017/01/03 PHP
PHP中include和require的区别实例分析
2017/05/07 PHP
ThinkPHP5.0框架控制器继承基类和自定义类示例
2018/05/25 PHP
24款非常有用的 jQuery 插件分享
2011/04/06 Javascript
JavaScript Memoization 让函数也有记忆功能
2011/10/27 Javascript
基于JQuery 滑动与动画的说明介绍
2013/04/18 Javascript
非常好用的JsonToString 方法 简单实例
2013/07/18 Javascript
Javascript 命名空间模式
2013/11/01 Javascript
Iframe 自动适应页面的高度示例代码
2014/02/26 Javascript
jquery禁用右键示例
2014/04/28 Javascript
js实现的二级横向菜单条实例
2015/08/22 Javascript
jQuery简单实现input文本框内灰色提示文本效果的方法
2015/12/02 Javascript
jQuery解析返回的xml和json方法详解
2017/01/05 Javascript
浅谈sass在vue注意的地方
2017/08/10 Javascript
vue js秒转天数小时分钟秒的实例代码
2018/08/08 Javascript
css配合JavaScript实现tab标签切换效果
2018/10/11 Javascript
JS原型与继承操作示例
2019/05/09 Javascript
利用Python开发实现简单的记事本
2016/11/15 Python
解决DataFrame排序sort的问题
2018/06/07 Python
对python添加模块路径的三种方法总结
2018/10/16 Python
python 获得任意路径下的文件及其根目录的方法
2019/02/16 Python
Pandas DataFrame中的tuple元素遍历的实现
2019/10/23 Python
Python.append()与Python.expand()用法详解
2019/12/18 Python
GNC健安喜官方海外旗舰店:美国著名保健品牌
2017/01/04 全球购物
Radley英国官网:英国莱德利小狗包
2019/03/21 全球购物
幼儿园消防演练方案
2014/02/13 职场文书
专科应届毕业生求职信
2014/06/04 职场文书
公司户外活动总结
2014/07/04 职场文书
岗位竞聘报告范文
2014/11/06 职场文书
2014年新教师工作总结
2014/11/08 职场文书
新学期主题班会
2015/08/17 职场文书
公司财务制度:成本管理控制制度模板
2019/11/19 职场文书
MySQL Shell的介绍以及安装
2021/04/24 MySQL