JavaScript:想把类数组转数组,`Array.from` 比手动循环省点事

41 次浏览3 条回复

有些 DOM 集合、Set、字符串这种东西,想先变成普通数组再处理,Array.from() 挺顺手。

环境:Node.js 18+ 或现代浏览器。可以建个 array-from-demo.mjs

const set = new Set(['a', 'b', 'c'])
console.log(Array.from(set))

const chars = Array.from('开发')
console.log(chars)

const numbers = Array.from({ length: 5 }, (_, i) => i + 1)
console.log(numbers)

跑一下:

node array-from-demo.mjs

大概会看到:

[ 'a', 'b', 'c' ]
[ '开', '发' ]
[ 1, 2, 3, 4, 5 ]

我觉得它适合那种先把可迭代对象拉平,再接 mapfilter 的小场景。生成固定长度数组时也能用,不过复杂一点的初始化还是单独写清楚更好读。

还有个小坑是它会吃第二个参数当 mapper,用来边转边处理挺方便:

const ids = Array.from({ length: 3 }, (_, i) => `item-${i + 1}`)
console.log(ids)

比先 Array.from(...).map(...) 少绕一圈。不过 mapper 里如果逻辑变长,我也会拆出去,不然读起来容易挤在一行里。

Array.from 跟展开运算符还有个区别挺实用:它能处理这种只有 length 的类数组对象,... 不行,因为它不是 iterable。

const likeArray = { 0: 'a', 1: 'b', length: 2 }

console.log(Array.from(likeArray))
// console.log([...likeArray]) // TypeError

所以 DOM 里的 NodeList 用哪个都还好,但碰到老一点的类数组对象,Array.from 会更稳。

补一个容易忽略的点:Array.from 转 DOM 集合时会拿到一个当时的快照,后面再对这个数组 filtersort 就不会影响原来的 DOM 集合。

我一般是需要多次遍历或要改顺序时才转;只扫一遍的话直接 for...of 也挺清楚,没必要为了转数组而转。