JavaScript中判断对象类型的几种方法总结


Posted in Javascript onNovember 11, 2013

我们知道,JavaScript中检测对象类型的运算符有:typeof、instanceof,还有对象的constructor属性:

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>

在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的面向对象(一)
Nov 09 Javascript
DHTML 中的绝对定位
Nov 26 Javascript
jquery一般方法介绍 入门参考
Jun 21 Javascript
node.js实现多图片上传实例
Jun 03 Javascript
jQuery制作拼图小游戏
Jan 12 Javascript
javascript面向对象快速入门实例
Jan 13 Javascript
js拆分字符串并将分割的数据放到数组中的方法
May 06 Javascript
JS中如何实现点击a标签返回页面顶部的问题
Jan 19 Javascript
Vue中自定义全局组件的实现方法
Dec 08 Javascript
vue修改对象的属性值后页面不重新渲染的实例
Aug 09 Javascript
element-ui组件table实现自定义筛选功能的示例代码
Mar 15 Javascript
Vue仿百度搜索功能
Dec 28 Vue.js
在页面中js获取光标/鼠标的坐标及光标的像素坐标
Nov 11 #Javascript
js中关于一个分号的崩溃示例
Nov 11 #Javascript
javascript中怎么做对象的类型判断
Nov 11 #Javascript
jquery隐藏标签和显示标签的实例
Nov 11 #Javascript
jquery(hide方法)隐藏指定元素实例
Nov 11 #Javascript
javascript垃圾收集机制与内存泄漏详细解析
Nov 11 #Javascript
JavaScript对内存分配及管理机制详细解析
Nov 11 #Javascript
You might like
jQuery+Ajax+PHP“喜欢”评级功能实现代码
2015/10/08 PHP
Zend Framework教程之Zend_Config_Ini用法分析
2016/03/23 PHP
PHP读取mssql json数据中文乱码的解决办法
2016/04/11 PHP
PHP 断点续传实例详解
2017/11/11 PHP
PHP 多进程与信号中断实现多任务常驻内存管理实例方法
2019/10/04 PHP
javascript使用数组的push方法完成快速排序
2014/09/15 Javascript
浅谈javascript中的闭包
2015/05/13 Javascript
javascript中JSON对象与JSON字符串相互转换实例
2015/07/11 Javascript
JavaScript通过使用onerror设置默认图像显示代替alt
2016/03/01 Javascript
vue组件实例解析
2017/01/10 Javascript
Angular2里获取(input file)上传文件的内容的方法
2017/09/05 Javascript
vue柱状进度条图像的完美实现方案
2019/08/26 Javascript
使用Vue调取接口,并渲染数据的示例代码
2019/10/28 Javascript
JS实现横向轮播图(初级版)
2020/06/24 Javascript
Python的Flask站点中集成xhEditor文本编辑器的教程
2016/06/13 Python
python timestamp和datetime之间转换详解
2017/12/11 Python
Python实现冒泡排序的简单应用示例
2017/12/11 Python
Python的SimpleHTTPServer模块用处及使用方法简介
2018/01/22 Python
在python中使用requests 模拟浏览器发送请求数据的方法
2018/12/26 Python
python 二维数组90度旋转的方法
2019/01/28 Python
浅谈Python中eval的强大与危害
2019/03/13 Python
使用Python的SymPy库解决数学运算问题的方法
2019/03/27 Python
PyQt5显示GIF图片的方法
2019/06/17 Python
Python爬虫 bilibili视频弹幕提取过程详解
2019/07/31 Python
Python学习工具jupyter notebook安装及用法解析
2020/10/23 Python
手把手教你从PyCharm安装到激活(最新激活码),亲测有效可激活至2089年
2020/11/25 Python
用css3制作纸张效果(外翻卷角)
2013/02/01 HTML / CSS
团委竞选演讲稿
2014/04/24 职场文书
节能宣传周活动总结
2014/05/08 职场文书
企业宣传工作方案
2014/06/02 职场文书
住宿生擅自离校检讨书
2014/09/22 职场文书
嘉年华活动新闻稿
2015/07/17 职场文书
2016小学新学期寄语
2015/12/04 职场文书
Python代码,能玩30多款童年游戏!这些有几个是你玩过的
2021/04/27 Python
Oracle 区块链表创建过程详解
2021/05/15 Oracle
使用Oracle跟踪文件的问题详解
2021/06/28 Oracle