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 相关文章推荐
js阻止默认事件与js阻止事件冒泡示例分享 js阻止冒泡事件
Jan 27 Javascript
js获取鼠标位置实例详解
Dec 09 Javascript
JavaScript几种数组去掉重复值的方法推荐
Apr 12 Javascript
jquery dialog获取焦点的方法
Feb 09 Javascript
Bootstrap modal 多弹窗之叠加显示不出弹窗问题的解决方案
Feb 23 Javascript
原生JS实现隐藏显示图片 JS实现点击切换图片效果
Jan 27 Javascript
javascript实现电脑和手机版样式切换
Nov 10 Javascript
jQuery中元素选择器(element)简单用法示例
May 14 jQuery
vue多层嵌套路由实例分析
Mar 19 Javascript
Vue 组件修改根实例的数据的方法
Apr 02 Javascript
Vue 实现监听窗口关闭事件,并在窗口关闭前发送请求
Sep 01 Javascript
vue3为什么要用proxy替代defineProperty
Oct 19 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
一个更简单的无限级分类菜单代码
2007/01/16 PHP
初步介绍PHP扩展开发经验分享
2012/09/06 PHP
基于PHP静态类的原罪详解
2013/05/06 PHP
php实现修改新闻时删除图片的方法
2015/05/12 PHP
PHP中的一些常用函数收集
2015/05/26 PHP
PHP简单获取及判断提交来源的方法
2016/04/22 PHP
PHP中仿制 ecshop验证码实例
2017/01/06 PHP
jquery 日期分离成年月日的代码
2010/05/14 Javascript
Jquery优化效率 提升性能解决方案
2010/09/06 Javascript
基于Jquery的表格隔行换色,移动换色,点击换色插件
2010/12/22 Javascript
jquery实现手机发送验证码的倒计时代码
2014/02/12 Javascript
跟我学习javascript的基本类型和引用类型
2015/11/16 Javascript
JavaScript正则表达式匹配 div  style标签
2016/03/15 Javascript
jQuery实现滚动到底部时自动加载更多的方法示例
2018/02/18 jQuery
Vue在 Nuxt.js 中重定向 404 页面的方法
2019/04/23 Javascript
详解python3百度指数抓取实例
2016/12/12 Python
对变量赋值的理解--Pyton中让两个值互换的实现方法
2017/11/29 Python
python入门:这篇文章带你直接学会python
2018/09/14 Python
Python流行ORM框架sqlalchemy安装与使用教程
2019/06/04 Python
pyqt5对用qt designer设计的窗体实现弹出子窗口的示例
2019/06/19 Python
win10安装tesserocr配置 Python使用tesserocr识别字母数字验证码
2020/01/16 Python
python等差数列求和公式前 100 项的和实例
2020/02/25 Python
python3注册全局热键的实现
2020/03/22 Python
使用python编写一个语音朗读闹钟功能的示例代码
2020/07/14 Python
python 如何对logging日志封装
2020/12/02 Python
基于html5 DeviceOrientation 实现微信摇一摇功能
2015/09/25 HTML / CSS
HTML5超文本标记语言的实现方法
2020/09/24 HTML / CSS
使用C#编写创建一个线程的代码
2013/01/22 面试题
新闻专业应届生求职信
2013/10/31 职场文书
关于赌博的检讨书
2014/01/08 职场文书
出生公证委托书
2014/04/03 职场文书
励志广播稿300字(5篇)
2014/09/15 职场文书
职工趣味运动会开幕词
2016/03/04 职场文书
Django实现drf搜索过滤和排序过滤
2021/06/21 Python
详解Vue的列表渲染
2021/11/20 Vue.js
公历12个月名称的由来
2022/04/12 杂记