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 相关文章推荐
newxtree.js代码
Mar 13 Javascript
关于二级域名下使用一级域名下的COOKIE的问题
Nov 07 Javascript
ASP.NET jQuery 实例14 在ASP.NET form中校验时间范围
Feb 03 Javascript
Javascript 中的 call 和 apply使用介绍
Feb 22 Javascript
jquery验证手机号码、邮箱格式是否正确示例代码
Jul 28 Javascript
jquery获取div距离窗口和父级dv的距离示例
Oct 10 Javascript
zepto.js中tap事件阻止冒泡的实现方法
Feb 12 Javascript
JS实现的鼠标跟随代码(卡通手型点击效果)
Oct 26 Javascript
最简单的JavaScript图片轮播代码(两种方法)
Dec 18 Javascript
Vuejs第十三篇之组件——杂项
Sep 09 Javascript
详解vue mixins和extends的巧妙用法
Dec 20 Javascript
ESLint 是如何检查 .vue 文件的
Nov 30 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 XML error parsing SOAP payload on line 1
2010/06/17 PHP
解析php中获取url与物理路径的总结
2013/06/21 PHP
php计算多个集合的笛卡尔积实例详解
2017/02/16 PHP
jQuery判断checkbox是否选中的小例子
2013/12/02 Javascript
js实现的标题栏新消息闪烁提示效果
2014/06/06 Javascript
JavaScript function 的 length 属性使用介绍
2014/09/15 Javascript
jquery文档操作wrap()方法实例简述
2015/01/10 Javascript
JavaScript中Boolean对象的属性解析
2015/10/21 Javascript
浅谈Sticky组件的改进实现
2016/03/22 Javascript
js判断某个字符出现的次数的简单实例
2016/06/03 Javascript
基于Bootstrap实现的下拉菜单手机端不能选择菜单项的原因附解决办法
2016/07/22 Javascript
微信小程序开发之好友列表字母列表跳转对应位置
2017/09/26 Javascript
vue2里面ref的具体使用方法
2017/10/27 Javascript
jq.ajax+php+mysql实现关键字模糊查询(示例讲解)
2018/01/02 Javascript
vue 监听某个div垂直滚动条下拉到底部的方法
2018/09/15 Javascript
详解JavaScript 新语法之Class 的私有属性与私有方法
2019/04/23 Javascript
小程序实现锚点滑动效果
2019/09/23 Javascript
实例分析JS中的相等性判断===、 ==和Object.is()
2019/11/17 Javascript
JsonServer安装及启动过程图解
2020/02/28 Javascript
vue实现评价星星功能
2020/06/30 Javascript
[02:14]2016国际邀请赛中国区预选赛Ehome晋级之路
2016/07/01 DOTA
python操作ie登陆土豆网的方法
2015/05/09 Python
用python实现刷点击率的示例代码
2019/02/21 Python
Grid 宫格常用布局的实现
2020/01/10 HTML / CSS
韩国女装NO.1网店:STYLENANDA
2016/09/16 全球购物
ProBikeKit澳大利亚:自行车套件,跑步和铁人三项装备
2016/11/30 全球购物
Lou & Grey美国官网:主打舒适性面料服饰
2017/12/21 全球购物
乌克兰的第一家手表店:Deka
2020/03/05 全球购物
OSPF有什么优点?为什么OSPF比RIP收敛快?
2013/02/13 面试题
销售职业生涯规划范文
2014/03/14 职场文书
ktv好的活动方案
2014/08/17 职场文书
房屋财产继承协议书范本
2014/11/03 职场文书
监考失职检讨书
2015/01/26 职场文书
个人总结与自我评价2015
2015/03/11 职场文书
因工资原因离职的辞职信范文
2015/05/12 职场文书
Docker与K8s关系介绍不会Docker也可以使用K8s
2022/06/25 Servers