JS 類數組對象(ArrayLike Object)的判斷

定義

在《JavaScript權威指南》中是這樣解釋類數組對象的:javascript

一種經常徹底合理的見解把擁有一個數值length屬性和對應非整數屬性的對象看作一種類型的數組。java

常見的類數組對象有函數中的arguments對象、HTMLCollection、NodeList等。數組

判斷方法

《JavaScript權威指南》中給出的判斷方法


function isArrayLike(o) {
    if(o &&                                    // o不是null、undefined等
       typeof o === 'object' &&                // o是對象
       isFinite(o.length) &&                   // o.length是有限數值
       o.length >= 0 &&                        // o.length爲非負值
       o.length === Math.floor(o.length) &&    // o.length是整數
       o.length < 4294967296)                  // o.length < 2^32
       return true
    else
       return false
}

在這裏我有一個疑問,根據定義,函數也有length數值屬性,應該也是類數組對象。但若是o是一個函數,那麼typeof o返回的是'function',並非'object',以至於調用isArrayLike函數會獲得false。(感受仍是由於定義不嚴謹致使的)函數

underscore中的實現


var isArrayLike = function(collection) {
    // 返回參數 collection 的 length 屬性值
    var length = getLength(collection);
    
    // length是數值,非負,且小於等於MAX_ARRAY_INDEX
    // MAX_ARRAY_INDEX = Math.pow(2, 53) - 1
    return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
  }

相對來講,underscore中的實現跟定義同樣寬鬆,函數也是類數組對象。甚至傳入數組,isArrayLike函數也會返回truecode

jQuery中的實現


function isArrayLike(obj) {
    // 若是obj非null、undefined等,有length屬性,則length等於obj.length
    // 不然,length爲false
    var length = !!obj && "length" in obj && obj.length,
        // 檢測obj的類型
        type = jQuery.type(obj)
        
        // 若是obj是function類型 或者是window對象 則返回false
        if (type === "function" || jQuery.isWindow(obj)) {
            return false
        }
        // obj自己是數組,則返回true
        // obj不是數組,但有length屬性且爲0,例如{length : 0},則返回true
        // obj不是數組,但有length屬性且爲整數數值,obj[length - 1]存在,則返回true
        return type === "array" || length === 0 ||
            typeof length === "number" && length > 0 && (length - 1) in obj;
}

結語

類數組對象的判斷,不一樣版本的返回結果有細微的差異。主要緣由是由於類數組對象不是規範的,因此不一樣項目的定義會有所不一樣。對象

相關文章
相關標籤/搜索