強壯的isArray函數(shù)
當前位置:點晴教程→知識管理交流
→『 技術(shù)文檔交流 』
在日常開發(fā)中,我們經(jīng)常需要判斷某個對象是否是數(shù)組類型的,在js中檢測對象類型的常見的方法有幾種: 1、typeof操作符。對于Function、String、Number、Undefined這幾種類型的對象來說,不會有什么問題,但是針對Array的對象就沒什么用途了: Js代碼 2、instanceof操作符。此操作符檢測對象的原型鏈是否指向構(gòu)造函數(shù)的prototype對象,恩,聽起來不錯,應(yīng)該可以解決我們的數(shù)組檢測問題: var arr = []; 3、對象的constructor屬性。除了instanceof,我們還可以利用每個對象都具有constructor的屬性來判斷其類型,于是乎我們可以這樣做: Js代碼 var arr = []; 貌似后兩個解決方案是無懈可擊的,但真的是這樣么?天有不測風(fēng)云,當你在多個frame中來回穿梭的時候,令人沮喪的問題出現(xiàn)了: Js代碼 由于每個iframe都有一套自己的執(zhí)行環(huán)境,跨frame實例化的對象彼此是不共享原型鏈的,因此導(dǎo)致上述檢測代碼失效!怎么辦怎么辦??嗯,javascript是動態(tài)語言,或許萬金油“鴨式辨型”(duck type)可以助我們一臂之力“如果它走起路來像鴨子,叫起來也像鴨子,那就當他是鴨子吧”,同理,可以檢測某些數(shù)組對象特有的能力來做判斷,這個法子已經(jīng)有人用了,比如Prototype框架,來看看它實現(xiàn)的Object.isArray方法: Js代碼 isArray: function(object) { isArray:”object,你有splice、join這兩個數(shù)組特有的方法嗎?” Js代碼 var trickster = { splice: 1, join: 2 }; 沒錯,這個解決方案給人的感覺有點別扭,任何一個具有’splice’和’join’屬性的對象都能通過這個檢測!怎么辦怎么辦怎么辦??別著急,仔細想想,其實我們需要的是一個能取得對象實際類型,而且又能跨frame使用的方法即可。這不,細心的老外在翻閱ECMA262標準的時候發(fā)現(xiàn)了這個(btw,我也看了,怎么就沒發(fā)現(xiàn)這個用途呢,囧): ECMA-262 寫道 Object.prototype.toString( ) When the toString method is called, the following steps are taken: 上面的規(guī)范定義了Object.prototype.toString的行為:首先,取得對象的一個內(nèi)部屬性[[Class]],然后依據(jù)這個屬性,返回一個類似于”[object Array]“的字符串作為結(jié)果(看過ECMA標準的應(yīng)該都知道,[[]]用來表示語言內(nèi)部用到的、外部不可直接訪問的屬性,稱為“內(nèi)部屬性”)。利用這個方法,再配合call,我們可以取得任何對象的內(nèi)部屬性[[Class]],然后把類型檢測轉(zhuǎn)化為字符串比較,以達到我們的目的。還是先來看看在 ECMA標準中Array的描述吧: ECMA-262 寫道 new Array([ item0[, item1 [,…]]]) 于是乎,可以改寫之前的isArray函數(shù)以利用這個特性,如下: function isArray(o) { call改變toString的this引用為待檢測的對象,返回此對象的字符串表示,然后對比此字符串是否是’[object Array]‘,以判斷其是否是Array的實例。也許你要問了,為什么不直接o.toString()?嗯,雖然Array繼承自O(shè)bject,也會有 toString方法,但是這個方法有可能會被改寫而達不到我們的要求,而Object.prototype則是老虎的屁股,很少有人敢去碰它的,所以能一定程度保證其“純潔性”:) 與前面幾個方案不同,這個方法很好的解決了跨frame對象構(gòu)建的問題,經(jīng)過測試,各大瀏覽器兼容性也很好,可以放心使用。一個好消息是,很多框架,比如jQuery、Base2等等,都計劃借鑒此方法以實現(xiàn)某些特殊的,比如數(shù)組、正則表達式等對象的類型判定,不用我們自己寫了。 該文章在 2010/8/13 23:10:33 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |