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 相关文章推荐
html中table数据排序的js代码
Aug 09 Javascript
javascript 在firebug调试时用console.log的方法
May 10 Javascript
javascript 使用 NodeList需要注意的问题
Mar 04 Javascript
js网页实时倒计时精确到秒级
Feb 10 Javascript
ionic在开发ios系统微信时键盘挡住输入框的解决方法(键盘弹出问题)
Sep 06 Javascript
基于JS实现横线提示输入验证码随验证码输入消失(js验证码的实现)
Oct 27 Javascript
原生和jQuery的ajax用法详解
Jan 23 Javascript
Bootstrap Table使用整理(二)
Jun 09 Javascript
AngularJS中ng-class用法实例分析
Jul 06 Javascript
angular2+node.js express打包部署的实战
Jul 27 Javascript
浅谈Vue 数据响应式原理
May 07 Javascript
Vue.js 图标选择组件实践详解
Dec 03 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
关于时间计算的结总
2006/12/06 PHP
PHP+memcache实现消息队列案例分享
2014/05/21 PHP
详解laravel安装使用Passport(Api认证)
2018/07/27 PHP
基于laravel Request的所有方法详解
2019/09/29 PHP
CSS+Table图文混排中实现文本自适应图片宽度(超简单+跨所有浏览器)
2009/02/14 Javascript
Javascript JSQL,SQL无处不在,
2010/05/05 Javascript
js href的用法
2010/05/13 Javascript
Jquery Select操作方法集合脚本之家特别版
2010/05/17 Javascript
JavaScript 原型继承
2011/12/26 Javascript
js实现简单登录功能的实例代码
2013/11/09 Javascript
JQuery右键菜单插件ContextMenu使用指南
2014/12/19 Javascript
Bootstrap每天必学之模态框(Modal)插件
2016/04/26 Javascript
浅谈Javascript中的12种DOM节点类型
2016/08/19 Javascript
Bootstrap警告(Alerts)的实现方法
2017/03/22 Javascript
JS简单判断滚动条的滚动方向实现方法
2017/04/28 Javascript
Vue-component全局注册实例
2018/09/06 Javascript
使用taro开发微信小程序遇到的坑总结
2019/04/08 Javascript
vue实现配置全局访问路径头(axios)
2019/11/01 Javascript
Vue-drag-resize 拖拽缩放插件的使用(简单示例)
2019/12/04 Javascript
vue使用map代替Aarry数组循环遍历的方法
2020/04/30 Javascript
jQuery实现动态向上滚动
2020/12/21 jQuery
[04:40]2016个国际邀请赛中国区预选赛场地——华西村观战指南
2016/06/25 DOTA
Python实现豆瓣图片下载的方法
2015/05/25 Python
python 中字典嵌套列表的方法
2018/07/03 Python
解决Numpy中sum函数求和结果维度的问题
2019/12/06 Python
python绘制封闭多边形教程
2020/02/18 Python
Python实现一个简单的毕业生信息管理系统的示例代码
2020/06/08 Python
python如何实现word批量转HTML
2020/09/30 Python
网易微博Web App用HTML5开发的过程介绍
2012/06/13 HTML / CSS
公司财务工作总结的自我评价
2013/11/23 职场文书
零件设计自荐信范文
2013/11/27 职场文书
学校介绍信范文
2014/01/14 职场文书
承诺书范文
2014/06/03 职场文书
餐厅服务员岗位职责
2015/02/09 职场文书
关于空气污染危害的感想
2015/08/11 职场文书
Redis分布式锁Redlock的实现
2021/08/07 Redis