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 相关文章推荐
jQuery中wrapAll()方法用法实例
Jan 16 Javascript
jQuery经过一段时间自动隐藏指定元素的方法
Mar 17 Javascript
如何使用Bootstrap的modal组件自定义alert,confirm和modal对话框
Mar 01 Javascript
BootStrap框架个人总结(bootstrap框架、导航条、下拉菜单、轮播广告carousel、栅格系统布局、标签页tabs、模态框、菜单定位)
Dec 01 Javascript
JS实现两周内自动登录功能
Mar 23 Javascript
ES6中Iterator与for..of..遍历用法分析
Mar 31 Javascript
JavaScript输入框字数实时统计更新
Jun 17 Javascript
如何用input标签和jquery实现多图片的上传和回显功能
May 16 jQuery
vue实现div拖拽互换位置
Jul 29 Javascript
微信小程序实现富文本图片宽度自适应的方法
Jan 20 Javascript
vue使用Font Awesome的方法步骤
Feb 26 Javascript
Vue实现小购物车功能
Dec 21 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
php预定义变量使用帮助(带实例)
2013/10/30 PHP
php计划任务之验证是否有多个进程调用同一个job的方法
2015/12/07 PHP
PHP使用PHPExcel实现批量上传到数据库的方法
2017/06/08 PHP
增强的 JavaScript 的 trim 函数的代码
2007/08/13 Javascript
读JavaScript DOM编程艺术笔记
2011/11/15 Javascript
同一页面多个商品倒计时JS 基于面向对象的javascript
2012/02/16 Javascript
Javascript图像处理—为矩阵添加常用方法
2012/12/27 Javascript
贴近用户体验的Jquery日期、时间选择插件
2015/08/19 Javascript
关于RequireJS的简单介绍即使用方法
2016/10/20 Javascript
JavaScript实现弹出广告功能
2017/03/30 Javascript
微信小程序实现发送模板消息功能示例【通过openid推送消息给用户】
2019/05/05 Javascript
vue实现歌手列表字母排序下拉滚动条侧栏排序实时更新
2019/05/14 Javascript
vue cli3.0 引入eslint 结合vscode使用
2019/05/27 Javascript
17道题让你彻底理解JS中的类型转换
2019/08/08 Javascript
Nodejs实现WebSocket代码实例
2020/05/19 NodeJs
Python学习资料
2007/02/08 Python
Python中sort和sorted函数代码解析
2018/01/25 Python
网易2016研发工程师编程题 奖学金(python)
2019/06/19 Python
Django自定义用户表+自定义admin后台中的字段实例
2019/11/18 Python
用Python实现定时备份Mongodb数据并上传到FTP服务器
2021/01/27 Python
CSS3实现内凹圆角的实例代码
2017/05/04 HTML / CSS
分享全球十款超强HTML5开发工具
2014/05/14 HTML / CSS
夏洛特和乔治婴儿和儿童时装精品店:Charlotte and George
2018/06/06 全球购物
世界各地的当地人的食物体验:Eatwith
2019/07/26 全球购物
波兰家居饰品和厨房配件网上商店:Maleomi
2020/12/15 全球购物
车间组长岗位职责
2013/12/20 职场文书
个人能力自我鉴赏
2014/01/25 职场文书
中学生班主任评语
2014/01/30 职场文书
2014大学生全国两会学习心得体会
2014/03/13 职场文书
合伙经营协议书范本
2014/09/13 职场文书
幼儿园小班家长评语
2014/12/30 职场文书
2015年度信用社工作总结
2015/05/04 职场文书
上班迟到检讨书范文
2015/05/06 职场文书
2015年销售助理工作总结
2015/05/11 职场文书
迎客户欢迎词三篇
2019/09/27 职场文书
详解CocosCreator消息分发机制
2021/04/16 Javascript