资讯专栏INFORMATION COLUMN

JS 类数组对象(ArrayLike Object)的判断

NotFound / 3279人阅读

摘要:定义在权威指南中是这样解释类数组对象的一种常常完全合理的看法把拥有一个数值属性和对应非整数属性的对象看做一种类型的数组。常见的类数组对象有函数中的对象等。主要原因是因为类数组对象不是规范的,所以不同项目的定义会有所不同。

定义

在《JavaScript权威指南》中是这样解释类数组对象的:

一种常常完全合理的看法把拥有一个数值length属性和对应非整数属性的对象看做一种类型的数组。

常见的类数组对象有函数中的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函数也会返回true

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

类数组对象的判断,不同版本的返回结果有细微的差别。主要原因是因为类数组对象不是规范的,所以不同项目的定义会有所不同。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/91127.html

相关文章

  • js 面试官想了解你有多理解call,apply,bind?

    摘要:返回值这段在下方应用中有详细的示例解析。回调函数丢失的解决方案绑定回调函数的指向这是典型的应用场景绑定指向,用做回调函数。 showImg(https://segmentfault.com/img/remote/1460000019971331?w=1024&h=680); 函数原型链中的 apply,call 和 bind 方法是 JavaScript 中相当重要的概念,与 this...

    wuaiqiu 评论0 收藏0
  • 深入理解JavaScript数组

    摘要:但是,我们可以借用类数组方法不难看出,此时的在调用数组原型方法时,返回值已经转化成数组了。很多时候,深入看看源代码也会让你对这个理解的更透彻。的前端乐园原文链接深入理解类数组 起因 写这篇博客的起因,是我在知乎上回答一个问题时,说自己在学前端时把《JavaScript高级程序设计》看了好几遍。于是在评论区中,出现了如下的对话:showImg(https://segmentfault.c...

    Towers 评论0 收藏0
  • 数组使用总结— (js基础复习第2期)

    摘要:前一个值,当前值,索引,数组对象产生新数组的迭代器方法类似,对数组的每个元素使用某个函数,并返回新数组和相似,传入一个返回值为布尔类型的函数。 1. 前言 数组真的是每天用了,但是有很多方法都是记不住,总是要百度查,很烦,所以才写了个数组使用总结,有什么不对的希望大家指出来。 2. 思路 先看看这些问题都记得很清楚么? 创建数组,怎么创建数组的 数组的构造方法Array有哪些方法?E...

    zhigoo 评论0 收藏0
  • 前端小知识10点(2019.6.25)

    摘要:前言这里记录我工作学习中值得注意的小知识点,希望对你有所帮助。循环的语法在单次循环开始前执行是单次循环的条件这里即存在是单次循环结束后执行说明在单次循环开始前执行是单次循环的条件这里即存在是单次循环结束后执行。 showImg(https://segmentfault.com/img/remote/1460000019583410); 前言:这里记录我工作、学习中值得注意的小知识点,希...

    wangzy2019 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<