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

结语

类数组对象的判断,不一样版本的返回结果有细微的差异。主要缘由是由于类数组对象不是规范的,因此不一样项目的定义会有所不一样。对象

相关文章
相关标签/搜索