JS教程:数组类型检测和集合检测

2016-02-20 00:51 5 1 收藏

有一种朋友不在生活里,却在生命力;有一种陪伴不在身边,却在心间。图老师即在大家的生活中又在身边。这么贴心的服务你感受到了吗?话不多说下面就和大家分享JS教程:数组类型检测和集合检测吧。

【 tulaoshi.com - Web开发 】

Question:编写一个函数 isArray(testVar) 。当testVar是数组类型时,返回1;当testVar是集合时,返回2;其他情况返回0。Solution:一、数组类型检测(1)检测构造函数

本来这应该是最简单的事情,Javascript中提供了instanceof运算符,可以检测某个变量是否某种类型的实例,一般情况下可以这样检测数组:testVar instanceof Array == true。但是,在跨frame的时候,等式不成立。假设测试页test.html的代码如下:

script language=javascript type=text/javascript
//![CDATA[
function isArray(testVar) {
 return testVar instanceof Array;
}
//]]
/script
iframe id=testFrame src=testframe.html/iframe

testframe.html的代码如下:

script language=javascript type=text/javascript
//![CDATA[
function isArray(testVar) {
 alert(parent.isArray([]));
}
//]]
/script

输出的内容是false。似乎每个页面都有自己的Array类型,如果把isArray改写一下,输出的就是true:

function isArray(testVar) {
 return testVar instanceof document.getElementById(testFrame).contentWindow.Array;
}

检测testVar.constructor也会出现类似的情况。因此,这种方法不可行。

(2)检测特性

通过数组独有的函数进行检测,比如检测testVar.sort是否未定义。这种方法在一般情况下也是可行的,但是健壮性不足。如果给testVar动态加了一个sort方法,判断就会失误。

(3)jQuery1.3带来了曙光

没什么好说的,直接看代码,太牛了:

if (Object.prototype.toString.call(testVar) === [object Array]) return 1;

二、集合检测

所谓的集合就是可以通过下标访问但又不是数组的类型。已知的Javascript集合有两种,一种是HtmlCollection,另一种是函数的参数arguments

(1)排他法

在已知testVar不是数组的情况下,先检测它的length属性是否存在。包含length属性的类型也不少,比如window、String、某些HtmlElement。所以要检测的特征非常多:

testVar.length != null &&
!testVar.alert && // 不是window
!testVar.charAt && // 不是String
!testVar.nodeType // 不是HtmlElement

由于其他情况实在太多,容易出现疏漏,所以最终还是没有采取这种办法。

(2)检测特性

已知的集合只有两种,所以还是检查这两种集合的特性吧。HtmlCollection有item方法,而arguments则有callee属性:

if (testVar.item || testVar.callee) return 2;

这时,select元素开始搅局。它竟然包含HtmlCollectiond的所有特性。于是,还是要判断nodeType:

if (!testVar.nodeType && testVar.item || testVar.callee) return 2;

select元素被轰走了,万恶的ie开始捣乱。首先是XML的问题,某个ajax回调函数:

function onSuccess(xhr) {
var xmlDoc = xhr.responseText;
alert(xmlDoc.getElementsByTagName); // ie下报错
var root = xmlDoc.getElementsByTagName(root);
alert(root.item) // ie下报错
}

也就是说,在ie下,只要尝试检测xml节点或xml节点集合的方法都会报错。幸好还可以用typeof去对付它们。

function onSuccess(xhr) {
var xmlDoc = xhr.responseText;
alert(typeof(xmlDoc.getElementsByTagName)); // ie下输出unknown
var root = xmlDoc.getElementsByTagName(root);
alert(typeof(root.item)) // ie下输出unknown
}

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/webkaifa/)

因此,代码就改成:

if (!testVar.nodeType && typeof testVar.item != undefined || testVar.callee) return 2;

其次,是window对象的问题:ie下的window对象也有item方法。所以还是要检测window对象:

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/webkaifa/)

if (!testVar.nodeType && typeof testVar.item != undefined && !testVar.alert || testVar.callee) return 2;

虽然检测特性容易出现失误,但是目前也只有这种办法了。

至此,终于折腾完,整个函数简写后就是:

var isArray = function(testVar) {
 return Object.prototype.toString.call(testVar) === [object Array] ? 1 :  testVar.callee || (typeof testVar.item != undefined && !testVar.nodeType && !testVar.alert) ? 2 : 0;
};

目前还不知道有没有疏漏。

来源:http://www.tulaoshi.com/n/20160220/1632688.html

延伸阅读
标签: Web开发
其他插件改一下sID就行了  系统正在检测你的播放器版本... [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]
标签: ASP
  经常见到cint和clng的溢出出错,如果有检测函数就不会出这个问题,下面这两个函数是应朋友要求写的,看一下吧 '检测字符串是否是整数 function Is_Int(a_str)    if not isnumeric(a_str) or len(str) 5 then       Is_Int = false       exit function...
精子能美容吗? 精子,俗称精液,由男性体内产生,和卵子相结合后诞生新生命。传闻精子可以助女人美颜,这是真的吗?精子能美容吗? 精液由精子和精浆组成,而精浆里含有果糖和蛋白质,除此之外,还有一些矿物质、酵素等物质,这些都是精子的营养物。 从原理上来说,精子的成分可以起到这样的作用。但是,目前...
标签: 怀孕
如何进行胎心监护呢?胎心监护是定期检测项目,准妈妈要重视。这是一种了解胎儿发育的产检方法。那么, 胎心监护的作用 究竟是什么呢?今天,小编就来详细告诉你。 胎心监护的方法 准备胎心仪,心情平稳的情况下,平躺,胎心声是如钟表的“嗒嗒声”,在腹部同一位置,缓慢持续加压,如在这一位置没有听到,以与这一位置半径5cm转移。 6个...
标签: 孕前
女人什么时候容易受孕?    女生最敏感的时期是在月经后的两周,也就是女人性感受的时期,此时就是女人最容易怀孕的时期。男人们肯定还会问,女人们在什么时候性能达到高潮,答案就在下文。     女人什么时候容易受孕     近日,据美国某杂志报道,如果男性可以读懂...

经验教程

342

收藏

47
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部