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 相关文章推荐
客户端限制只能上传jpg格式图片的js代码
Dec 09 Javascript
利用Javascript判断操作系统的类型实现不同操作系统下的兼容性
Jan 29 Javascript
jquery与prototype框架的详细对比
Nov 21 Javascript
JS 作用域与作用域链详解
Apr 07 Javascript
JS中Location使用详解
May 12 Javascript
如何消除inline-block属性带来的标签间间隙
Mar 31 Javascript
weex slider实现滑动底部导航功能
Aug 28 Javascript
详解Angularjs 自定义指令中的数据绑定
Jul 19 Javascript
Layui 导航默认展开和菜单栏选中高亮设置的方法
Sep 04 Javascript
layui table设置某一行的字体颜色方法
Sep 05 Javascript
vue倒计时刷新页面不会从头开始的解决方法
Mar 03 Javascript
JS实现公告上线滚动效果
Jan 10 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 按位与或 (^ 、&amp;)
2013/06/21 PHP
php中 $$str 中 &quot;$$&quot; 的详解
2015/07/06 PHP
PHP实现根据数组某个键值大小进行排序的方法
2018/03/13 PHP
php通过各种函数判断0和空
2020/07/04 PHP
php实现微信原生支付(扫码支付)功能
2018/05/30 PHP
php根据命令行参数生成配置文件详解
2019/03/15 PHP
基于php+MySql实现学生信息管理系统实例
2020/08/04 PHP
[JS源码]超长文章自动分页(客户端版)
2007/01/09 Javascript
奇妙的js
2007/09/24 Javascript
使用Grunt.js管理你项目的应用说明
2013/04/24 Javascript
jquery的选择器的使用技巧之如何选择input框
2013/09/22 Javascript
js arguments,jcallee caller用法总结
2013/11/30 Javascript
使用JQ来编写最基本的淡入淡出效果附演示动画
2014/10/31 Javascript
Jquery对象和Dom对象的区别分析
2014/11/20 Javascript
简介JavaScript中Boolean.toSource()方法的使用
2015/06/05 Javascript
jQuery实现隔行变色的方法分析(对比原生JS)
2016/11/18 Javascript
js Canvas绘制圆形时钟教程
2017/02/06 Javascript
vue2笔记 — vue-router路由懒加载的实现
2017/03/03 Javascript
详解vue 模拟后台数据(加载本地json文件)调试
2017/08/25 Javascript
web前端vue之CSS过渡效果示例
2018/01/10 Javascript
微信小程序实现注册登录功能(表单校验、错误提示)
2019/12/10 Javascript
[03:37]2014DOTA2国际邀请赛 主赛事第一日胜者组TOPPLAY
2014/07/19 DOTA
Python3.5.3下配置opencv3.2.0的操作方法
2018/04/02 Python
Python numpy中矩阵的基本用法汇总
2019/02/12 Python
Python PyQt5整理介绍
2020/04/01 Python
python解决OpenCV在读取显示图片的时候闪退的问题
2021/02/23 Python
HTML5实现简单图片上传所遇到的问题及解决办法
2016/01/20 HTML / CSS
俄罗斯运动鞋商店:Sneakerhead
2018/05/10 全球购物
德国综合购物网站:OTTO
2018/11/13 全球购物
美国时尚大码女装购物网站:Avenue
2019/05/24 全球购物
争做文明公民倡议书
2014/08/29 职场文书
律师授权委托书范本
2014/10/07 职场文书
2015年学校禁毒工作总结
2015/05/27 职场文书
冰雪公主观后感
2015/06/16 职场文书
Python爬虫中urllib3与urllib的区别是什么
2021/07/21 Python
一次Mysql update sql不当引起的生产故障记录
2022/04/01 MySQL