扩展运算符与非数组的可迭代对象

回顾一下第七章,扩展运算符(…​)可以被用于将一个 Set 转换为数组,例如:

let set = new Set([1, 2, 3, 3, 3, 4, 5]),
    array = [...set];

console.log(array);             // [1,2,3,4,5]

此代码在数组字面量中使用扩展运算符,以便将 set 中的值填充到数组。扩展运算符能作用于所有可迭代对象,并且会使用默认迭代器来判断需要使用哪些值。所有的值都从迭代器中被读取出来并插入数组,遵循迭代器返回值的顺序。此例工作正常是由于 Set 是可迭代对象,但这种方式同样还能用于任意的可迭代对象。此处有另一个例子:

let map = new Map([ ["name", "Nicholas"], ["age", 25]]),
    array = [...map];

console.log(array);         // [ ["name", "Nicholas"], ["age", 25]]

此处的扩展运算符将 map 转换为一个由数组构成的数组。由于 Map 的默认迭代器返回的是键值对,最终的数组看起来与调用 new Map() 时所传入的参数一模一样。

你能不限次数地在数组字面量中使用扩展运算符,而且可以在任意位置用扩展运算符将可迭代对象的多个项插入数组,这些项在新数组中将会出现在扩展运算符对应的位置, 例如:

let smallNumbers = [1, 2, 3],
    bigNumbers = [100, 101, 102],
    allNumbers = [0, ...smallNumbers, ...bigNumbers];

console.log(allNumbers.length);     // 7
console.log(allNumbers);    // [0, 1, 2, 3, 100, 101, 102]

此处的扩展运算符使用 smallNumbersbigNumbers 中的数据来创建 allNumbers 数组。在 allNumbers 被创建时,值在其中的排列顺序与数组被添加的顺序一致:首先是 0,其次是来自 smallNumbers 数组的元素,最后是来自 bigNumbers 数组的元素。原始数组并没有被改变,只是它们的值被复制到了 allNumbers 数组中。

既然扩展运算符能用在任意可迭代对象上,它就成为了将可迭代对象转换为数组的最简单方法。你可以将字符串转换为包含字符(而非码元)的数组,也能将浏览器中的 NodeList 对象转换为节点数组。

现在你已基本了解迭代器是如何工作的(包括 for-of 与扩展运算符),是时候去看看迭代器的一些更复杂用法了。