繁体   English   中英

为什么在这种情况下调用ES6会“产生”一个保留字?

[英]Why is ES6 “yield” a reserved word when called in this context?

我正在使用节点4.1.1。 当我运行此代码时

"use strict";

function *generator() {
  let numbers = [1,2,3,4,5];
  numbers.map(n => yield (n + 1));
}

for (var n of generator()) {
  console.log(n);
}

我收到这个错误

  numbers.map(n => yield (n + 1));
                   ^^^^^

SyntaxError: Unexpected strict mode reserved word

如果我将代码重新排列为此

"use strict";

function *generator() {
  let numbers = [1,2,3,4,5];
  let higherNumbers = numbers.map(n => n + 1);
  for(let i=0;i<higherNumbers.length;i++) {
    yield higherNumbers[i];
  }
}

for (var n of generator()) {
  console.log(n);
}

我得到了预期的结果。

为什么第二个工作,第一个失败? 当然,如果保留一个关键字,它会在所有上下文中保留,而不仅仅是在箭头函数中使用它?

你可以做任何事情而不是一切 - 学会委派

我们先来看两个例子

产量

 function* generator(numbers) { yield numbers.map(x => x + 1); } for (let n of generator([1,2,3])) console.log(n); // [ 2, 3, 4 ] 

我们的for循环记录了生成器产生的每个值。 在我们的生成器中,我们有一个yield调用,它将产生numbers.map调用的结果,这是一个新的Array。 因为只有一个产量,所以唯一记录的值是[2,3,4]

yield*

因此,在上述情况下, yield显然不会起作用。 我们必须尝试别的东西。

 function* generator(numbers) { yield* numbers.map(x => x + 1); } for (let n of generator([1,2,3])) console.log(n); // 2 // 3 // 4 

同样,我们for循环日志的每个值yield由发电机编。 在我们的生成器中,我们产生了与numbers.map调用相同的结果,但这次我们使用yield* ,它通过委托产生

那我们收获的是什么? 好吧,Array有一个内置的生成器, Array.prototype[Symbol.iterator] 所以在这一点上, for循环基本上直接通过Array提供的生成器步进。 由于数组有3个值,我们看到3个记录值。


注视着眼睛

所以我们使用Array.prototype.map迭代numbers一次但是然后我们使用for循环遍历中间数组? 好像浪费不是吗?

让我们回顾一下您的原始代码

function *generator() {
  let numbers = [1,2,3,4,5];
  numbers.map(n => yield (n + 1));
}

for (var n of generator()) {
  console.log(n);
}

请注意,您的numbers.map调用非常无意义。 Array.prototype.map创建一个新数组,但您的生成器不会对它执行任何操作。 所以, 真正你仅仅使用map迭代通的数字,不是因为你真正关心的返回值map


说出你的意思,就是你所说的

好的,现在我们知道我们只关心通过数字迭代。 所以我们将按照JavaScript最了解的方式使用迭代

 function* generator(numbers) { for (let x of numbers) yield x + 1 } for (let n of generator([1,2,3])) console.log(n); // 2 // 3 // 4 

答对了。 没有棘手的yield* 没有双重迭代。 没有废话。

这是因为箭头功能不是发电机功能。 例如,

function temp() {
  yield 1;
}

我们可以期待这个吗? 不。因为temp不是发电机功能。 这同样适用于箭头功能。


FWIW,根据ECMAScript 2015规范,箭头函数中yield的使用是一个早期错误,按照本节的规定

ArrowFunction:ArrowParameters => ConciseBody

  • 如果ArrowParameters包含YieldExpressiontrue ,则为语法错误。

  • 如果ConciseBody包含YieldExpressiontrue ,则为语法错误。

那是因为箭头功能不是发电机。 如果我展开你的箭头功能,它看起来像:

function *generator() {      // <-- this is your generator function
  let numbers = [1,2,3,4,5];
  numbers.map(function(n){   // <-- this one isn't a generator
    yield (n + 1)            // <-- there's your yield
  }.bind(this));
}
[1,2,3,4,5].map(function*(v){yield v+1;}).reduce((accumulator, currentValue) => accumulator = [...accumulator].concat([...currentValue]))

说明...

[1,2,3,4,5].map(function*(v){yield v+1;})

将所有值打包到生成器中

(5)[发电机,发电机,发电机,发电机,发电机]

打开平面阵列

.reduce((accumulator, currentValue) => accumulator = [...accumulator].concat([...currentValue]))

(5)[2,3,4,5,6]

正常使用

[1,2,3,4,5].map(function*(v){yield v+1;}).forEach(v => console.log([...v][0]))

2

3

4

6

[... v] [0]有点丑,但它确实有效。

刚刚发现你可能会因为过早地关闭你的功能而遇到这种情况。

即太多了}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM