首先,计算... 右侧的表达式。也就是说,Array(5).keys() + 1 被评估,然后该评估的结果被传播。对表达式进行分组可能会使事情变得更清晰:
[...(Array(5).keys() + 1)]
所以,在上面,我们从计算Array(5).keys() + 1 的结果开始。 + 运算符在原始操作数之间工作。当您执行Array(5).keys() 时,您会得到一个未归类为原语的迭代器。因此,JS 会尝试将其转换为原语。当 JS 尝试在这种情况下将迭代器转换为原语时,它会尝试:
- 调用迭代器的
Symbol.toPrimitive 方法,因为它不存在,它继续尝试下一步
- 调用迭代器的
.valueOf() 方法。这成功了,但是它返回了迭代器,它不是一个原语,所以我们进入下一步
- 调用
.toString() 方法。这导致非对象类型(即:字符串),因此这是成功的。
当迭代器的.toString() 方法被调用时,它被评估为"[object Array Iterator]"。当它与数字 1 相加时,我们将字符串与数字连接(而不是相加),给出:
[..."[object Array Iterator]1"]
由于字符串是可迭代的,展开语法将使用字符串的迭代器循环遍历字符串中的代码点,从而使字符串的每个字符都成为自己的元素:
["[", "o", "b", "j", "e", "c", "t", " ", "A", "r", "r", "a", "y", " ", "I", "t", "e", "r", "a", "t", "o", "r", "]", "1"]
要为迭代器中的每个项目添加一个,您可以使用Array.from(),它可以接受一个迭代器,并对每个元素应用一个映射函数:
const res = Array.from(Array(5).keys(), i => i+1);
console.log(res);
由于 Array.from() 的参数不必是迭代器,您也可以只使用 Array(5) 并使用索引作为要添加的值:
const res = Array.from(Array(5), (_,i) => i+1);
console.log(res);