JS类数组对象及如何转变为真正的数组

什么是类数组对象?
简单来说: 具有length属性并且可以通过数字下标方式访问属性的对象就是类数组对象, 它不一定具有数组的方法( 你可以用 Object.getOwnPropertyNames(Array.prototype) 来看一个对象默认有哪些方法 ).
<<javascript权威指南>> 中判断类数组对象的一个方法:
// Determine if o is an array-like object.
// Strings and functions have numeric length properties, but are 
// excluded by the typeof test. In client-side JavaScript, DOM text
// nodes have a numeric length property, and may need to be excluded 
// with an additional o.nodeType != 3 (text node type) test.  
function isArrayLike(o) {
    if (o &&                                // o is not null, undefined, etc.
        typeof o === 'object' &&            // o is an object
        isFinite(o.length) &&               // o.length is a finite number
        o.length >= 0 &&                    // o.length is non-negative
        o.length===Math.floor(o.length) &&  // o.length is an integer
        o.length < 4294967296)              // o.length < 2^32
        return true;                        // Then o is array-like
    else
        return false;                       // Otherwise it is not
}

哪里会常用到类数组对象?
  1. arguments 就是类数组对象

  2. DOM( 用来操作XML,HTML的API ) 操作的返回值(i.e. document.getElementsByClassName() ) 通常就是类数组对象

类数组对象如何转变为真正的数组?
  • Array.from 方法从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例
console.log(Array.from('foo'));
// expected output: Array ["f", "o", "o"]

console.log(Array.from([1, 2, 3], x => x + x));
// expected output: Array [2, 4, 6]

  • Array.prototype.slice.call()

slice() 方法返回一个新的数组对象,这一对象是一个由 beginend 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变

getUserList(){
    const memberList = Array.prototype.slice.call($('#MemberList li'));
    // 省略其他代码
}
  • ES6展开运算符

展开语法(Spread syntax), 可以在函数调用/数组构造时, 将数组表达式或者string在语法层面展开;还可以在构造字面量对象时, 将对象表达式按key-value的方式展开。

getUserList(){
    const memberList = [...document.getElementsByTagName("li")];
    // 省略其他代码
}
  • 利用concat+apply

    getUserList(){
        const memberList = Array.prototype.concat.apply([], $('#MemberList li'));
        // 省略其他代码
    }
    
posted @ 2020-09-22 14:36  小蜗蜗蜗牛^o^  阅读(351)  评论(0编辑  收藏  举报