国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > JS > 正文

JS教程:數組類型檢測和集合檢測

2024-09-06 12:40:56
字體:
來源:轉載
供稿:網友

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”
}

因此,代碼就改成:

if (!testvar.nodetype && typeof testvar.item != “undefined” || testvar.callee) return 2;

其次,是window對象的問題:ie下的window對象也有item方法。所以還是要檢測window對象:

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;
};

目前還不知道有沒有疏漏。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 公主岭市| 永平县| 曲靖市| 宁城县| 惠来县| 潮安县| 承德市| 永兴县| 竹北市| 永吉县| 濮阳县| 县级市| 屯昌县| 濮阳市| 阿拉善左旗| 本溪| 昭平县| 上虞市| 清原| 常州市| 巴林右旗| 新竹市| 大石桥市| 赫章县| 万荣县| 天等县| 九台市| 临安市| 顺昌县| 玉龙| 介休市| 贵溪市| 望奎县| 临海市| 库伦旗| 广南县| 五莲县| 易门县| 湟源县| 宿松县| 婺源县|