类数组转化为数组
什么是类数组(Array Like)?
一个简单的定义,如果一个对象有 length
属性值,则它就是类数组
常见的类数组有哪些?
这在 DOM 中甚为常见,如各种元素检索 API 返回的都是类数组,如 document.getElementsByTagName
,document.querySelectorAll
等等。除了 DOM API 中,常见的 function
中的 arguments
也是类数组
将类数组转化为数组
ES6+
ES6
中有现成的 API:Array.from
1 | // [undefined, undefined, undefined] |
以及运算符 ...
扩展运算符,不过它只能作用于 iterable
对象,即拥有 Symbol(Symbol.iterator)
属性值的对象,意味着可以使用 for of
来循环迭代
1 | // 适用于 iterable 对象 |
但是严格意义上来说,它不能把类数组转化为数组,如 { length: 3 }
。它将会抛出异常
1 | // Uncaught TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator)) |
ES5
我们使用以下数据来代表类数组:
1 | const arrayLike = { |
在 ES5
中可以借用 Array API
通过 call/apply
改变 this
或者 arguments
来完成转化。
最常见的转换是 Array.prototype.slice
1 | Array.prototype.slice.call(arrayLike); |
由于借用 Array API
,一切以数组为输入,并以数组为输出的 API 都可以来做数组转换,如
Array
(借用 arguments)Array.prototype.concat
(借用 arguments)Array.prototype.slice
(借用 this)Array.prototype.map
(借用 this)Array.prototype.filter
(借用 this)
1 | Array.apply(null, arrayLike); |
稀疏数组 (sparse array)
使用 Array(n)
将会创建一个稀疏数组,为了节省空间,稀疏数组内含非真实元素,在控制台上将以 empty
显示
1 | > [,,,] |
总结
把类数组转化成数组最靠谱的方式是以下三个
1 | Array.from(arrayLike); |
以下几种方式需要考虑稀疏数组的转化
1 | Array.prototype.filter.call(divs, (x) => 1); |
以下方法要注意是否是 iterable object
1 | [...arrayLike]; |