javascript - 使用扩展语法创建一系列自然数

标签 javascript arrays ecmascript-6 iterator

一方面,缺少相当于 Python 3 的 range 是 ES6 中的一个烦恼。另一方面,有很多解决方法。我的问题是为什么我尝试过的一种解决方法确实有效。举例说明:

[...Array(10).keys()];

如果我觉得这个神秘的原因不是很明显,请注意 Array(10).keys() 至少显然是空的。

我知道这会浪费地创建两个数组,就像大多数流行的解决方法一样,并且(以创建生成器函数为代价)使用生成器可以避免这种情况。例如,

[...(function*(){let i = 0; while(i<10) yield i++;})()];

我的问题只是关于为什么第一个解决方法会产生预期的结果。

编辑:

从回答来看,有些人认为Array(10)的求值等同于Array.apply(null,Array(10))的求值.他们不是。例如,.hasOwnProperty(0) 对前者为 false 而对后者为 true。但是,我愿意被说服他们在某些重要方面是相同的,因为我在某些关键点上显然缺乏理解。我怀疑答案是遍历键的结果是由 length 属性决定的,这两者共享,而不是已经定义的实际数组索引。如果是这样,我想知道这种行为是规范的。

最佳答案

Array#keys返回一个数组 迭代器。 Spread 语法然后通过访问迭代器中的下一个值来完全耗尽该迭代器,直到没有更多值为止。然后它从迭代器中收集所有值并将它们散布到一个新数组中。

Array(10)创建一个 array exotic object它没有任何实际的整数索引键,只有一个 length 属性——所以它会是“空的”,但 Array(10).keys() 不是。事实是,使用 Array#keys doesn't depend on actual elements, just the length property .内部运作CreateArrayIterator通过内部 %ArrayIteratorPrototype% object 创建迭代器,从数组创建键迭代器.看着%ArrayIteratorPrototype%.next() ,您会看到使用了数组的长度。对于 Array#keys,索引不断递增,直到达到数组的长度。这就是迭代器的创建方式,它为您提供数组的所有键,而无需实际上一开始就说整数键。


如果您对抽象步骤感到好奇,请参阅 Section 12.2.5.2 ArrayAcculumation ECMAScript 语言规范,特别是 SpreadElement : ... AssignmentExpression 产品,它概述了逐步执行与传播语法结合使用的迭代器的过程。

要查看将这些值收集到新数组中的抽象步骤,请参阅 Section 12.2.5.3 Evaluation .具体来说,ArrayLiteral : [ ElementList ] 产生式是 [...Array.keys()] 的产生式。执行上述 ArrayAcculumation 过程,该过程聚合迭代迭代器并将它们设置到新数组中。

关于javascript - 使用扩展语法创建一系列自然数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48046113/

相关文章:

javascript - Safari 10.1 es6 模块示例

javascript - 如何向用户代理播放仅 JavaScript 音频 getUserMedia 流?

javascript - 如何将参数传递给函数调用以更改 css 样式?

javascript - 如何在 Canvas html5中获取上下文X和Y位置

python - 二维数组的 Numpy 重复

javascript - 返回 this 的 ES6 类方法无法由 stderr.on ('data' 调用)

javascript - 显示文本框值

javascript - 如何创建一个对数值数组进行排序并能够动态交换数组的函数?

java - 如何允许用户访问类的方法

javascript - Promise.all 不适用于异步函数数组