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实现的HashMap类代码
Jun 27 Javascript
Node.js中的事件驱动编程详解
Aug 16 Javascript
js监听鼠标点击和键盘点击事件并自动跳转页面
Sep 24 Javascript
JS 打印功能代码可实现打印预览、打印设置等
Oct 31 Javascript
VUE 更好的 ajax 上传处理 axios.js实现代码
May 10 Javascript
在vue.js中抽出公共代码的方法示例
Jun 08 Javascript
vue2.0的contextmenu右键弹出菜单的实例代码
Jul 24 Javascript
JS获取input[file]的值并显示在页面的实现方法
Mar 09 Javascript
vue增加强缓存和版本号的实现方法
May 01 Javascript
node实现socket链接与GPRS进行通信的方法
May 20 Javascript
vue基于v-charts封装双向条形图的实现代码
Dec 09 Javascript
JavaScript架构localStorage特殊场景下二次封装操作
Jun 21 Javascript
在页面中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
由php if 想到的些问题
2008/03/22 PHP
PHP mb_convert_encoding文字编码的转换函数介绍
2011/11/10 PHP
PHP代码优化之成员变量获取速度对比
2014/02/28 PHP
浅析php中json_encode()和json_decode()
2014/05/25 PHP
document.documentElement &amp;&amp; document.documentElement.scrollTop
2007/12/01 Javascript
ExtJS 2.0 GridPanel基本表格简明教程
2010/05/25 Javascript
cookie.js 加载顺序问题怎么才有效
2013/07/31 Javascript
JS脚本根据手机浏览器类型跳转WAP手机网站(两种方式)
2015/08/04 Javascript
jquery+css3实现网页背景花瓣随机飘落特效
2015/08/17 Javascript
IE8下jQuery改变png图片透明度时出现的黑边
2015/08/30 Javascript
JS模拟实现Select效果代码
2015/09/24 Javascript
jquery中取消和绑定hover事件的实现代码
2016/06/02 Javascript
JS中使用FormData上传文件、图片的方法
2016/08/07 Javascript
servlet+jquery实现文件上传进度条示例代码
2017/01/25 Javascript
JQuery validate 验证一个单独的表单元素实例
2017/02/17 Javascript
Vue组件之自定义事件的功能图解
2018/02/01 Javascript
三分钟学会用ES7中的Async/Await进行异步编程
2018/06/14 Javascript
在小程序Canvas中使用measureText的方法示例
2018/10/19 Javascript
JavaScript 作用域实例分析
2019/10/02 Javascript
python使用Tkinter显示网络图片的方法
2015/04/24 Python
Python语法快速入门指南
2015/10/12 Python
用生成器来改写直接返回列表的函数方法
2017/05/25 Python
对python中Matplotlib的坐标轴的坐标区间的设定实例讲解
2018/05/25 Python
python可视化实现代码
2019/01/15 Python
利用Python绘制Jazz网络图的例子
2019/11/21 Python
python中count函数简单用法
2020/01/05 Python
法国体育用品商店:GO Sport
2019/10/23 全球购物
面向游戏玩家和书呆子的极客订阅盒:Loot Crate
2020/11/25 全球购物
你的创业计划书怎样才能打动风投
2014/02/06 职场文书
晚会主持词开场白
2014/03/17 职场文书
2014年班主任工作总结
2014/11/08 职场文书
2015年工商所工作总结
2015/05/21 职场文书
2016年师德先进个人事迹材料
2016/02/29 职场文书
2019最新校园运动会广播稿!
2019/06/28 职场文书
MYSQL数据库使用UTF-8中文编码乱码的解决办法
2021/05/26 MySQL
Redis安装使用RedisJSON模块的方法
2022/03/23 Redis