【问题标题】:Creating an array from ES6 generator从 ES6 生成器创建数组
【发布时间】:2017-10-11 21:31:35
【问题描述】:

假设我想将 ES6 生成器的结果分配给数组变量。

function* gen() {
   for(let i = 0; i < 3; i++) {
       yield i;
   }
}

let [...b] = gen();
console.log(b); // [0, 1, 2]

这里b 将被分配[0, 1, 2]。为什么会这样?

【问题讨论】:

  • 这看起来……很疯狂。 我的第一次尝试应该是const b = Array.from(gen),我假设应该可以工作,因为生成器是可迭代的,而Array.from 是可迭代的。编辑:好的,关闭:const b = Array.from(gen()) 确实有效。

标签: javascript ecmascript-6 generator


【解决方案1】:

生成器在被调用时返回iterator。例如,我们可以使用 for … of 循环遍历迭代器:

for (const item of gen()) {
  console.log(item);
}

这只会遍历生成器中的每个项目:

0
1
2

如果我们调用 spread syntax: 也会发生同样的事情:

const res = [...gen()];

res 将是:

[0, 1, 2]

在您的示例中,您使用的是解构赋值。使用括号语法进行解构调用 iterable 来获取值(数组的原理相同)。示例:

const [a, b] = gen();
// a: 0, b: 1

由于您使用的是rest syntax,因此您基本上是在说:给我所有留在迭代器中的值,并将它们保存在变量b中:

let [...b] = gen();
// b: [0, 1, 2]

这适用于任何可迭代对象:

const [a, b, ...c] = 'hello';
// a: 'h', b: 'e', c: 'llo'

就个人而言,我发现以下几点更容易推理:

const res = [...gen()];

【讨论】:

  • 我同意你的最后一个例子:或者const res = Array.from(gen()) both 明确 说明你从生成器创建一个数组。一个版本通过使用数组括号来实现,另一个版本通过拼写句子“create from an Array”来实现。两者都更容易理解,因为它们之间的交互较少:解构赋值以及它如何与可迭代对象交互。
  • 谢谢菲利克斯,我把它做好了传播,但把它搞砸了;)
【解决方案2】:

我想我在this post 上找到了答案。这里的... 运算符是rest 运算符。当用于解构数组时,它将被解构的数组的所有未分配元素分配给另一个数组。 rest 运算符必须用于接收解构值的变量列表中的最后一项。例如:

let a = [1, 2, 3, 4, 5];
let [first, second, ...remainder] = a;

console.log(first); // 1
console.log(second); // 2
console.log(remainder); // [3, 4, 5]

在问题中,由于 b 是唯一被解构的东西,并且它使用了 rest 运算符,因此将整个数组分配给它。

ES6 似乎运行生成器并将结果转换为 = 右侧的数组。

【讨论】:

【解决方案3】:

对于从生成器函数实际创建数组,这里有一些非常好的答案。 我个人更喜欢Array.from

function* gen() {
   for(let i = 0; i < 3; i++) {
       yield i;
   }
}

const arr = Array.from(gen());
console.log(arr); // [0, 1, 2]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-18
    • 2018-01-24
    • 2016-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-16
    • 2017-06-12
    相关资源
    最近更新 更多