Javascript 为什么在这种情况下调用 ES6 “yield” 是保留字?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33316765/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is ES6 "yield" a reserved word when called in this context?
提问by Mike Hogan
I am using node 4.1.1. When I run this code
我正在使用节点 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);
}
I get this error
我收到这个错误
numbers.map(n => yield (n + 1));
^^^^^
SyntaxError: Unexpected strict mode reserved word
If I rearrange the code to be this
如果我将代码重新排列成这样
"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);
}
I get the expected result.
我得到了预期的结果。
Why does the second one work, and the first fail? And surely if a keyword is reserved, it's reserved in all contexts, not just when it's used in a arrow function?
为什么第二个有效,而第一个失败?当然,如果一个关键字被保留,它在所有上下文中都会被保留,而不仅仅是在箭头函数中使用时?
采纳答案by thefourtheye
It is because arrow functions are not generator functions. For example,
这是因为箭头函数不是生成器函数。例如,
function temp() {
yield 1;
}
Can we expect this to work? No. Because temp
is not a generator function. The same is applicable to arrow functions as well.
我们可以期望这有效吗?temp
不。因为不是生成器函数。这同样适用于箭头函数。
FWIW, the usage of yield
in an Arrow function is an early error as per the ECMAScript 2015 specification, as per this section,
FWIW,根据yield
ECMAScript 2015 规范,在箭头函数中的使用是早期错误,根据本节,
ArrowFunction : ArrowParameters => ConciseBody
It is a Syntax Error if ArrowParametersContains YieldExpressionis true.
It is a Syntax Error if ConciseBodyContains YieldExpressionis true.
ArrowFunction : ArrowParameters => ConciseBody
如果ArrowParameters包含YieldExpression为true ,则这是一个语法错误。
如果ConciseBodyContains YieldExpression为 true,则为语法错误。
回答by Thank you
You can do anything but not everything – Learn to delegate
你可以做任何事,但不能做任何事——学会委派
Let's first look at two examples
我们先来看两个例子
1. yield
1.产量
function* generator(numbers) {
yield numbers.map(x => x + 1);
}
for (let n of generator([1,2,3])) console.log(n);
// [ 2, 3, 4 ]
Our for
loop logs each value yielded by the generator. Inside our generator, we have a single yield
call which will yield the result of the numbers.map
call, which is a new Array. Because there is only a single yield, the only logged value is [2,3,4]
我们的for
循环记录了生成器产生的每个值。在我们的生成器中,我们有一个yield
调用将产生调用的结果numbers.map
,这是一个新的数组。因为只有一个产量,所以唯一记录的值是[2,3,4]
2. yield*
2. yield*
So yield
obviously won't work in the case above. We'll have to try something else.
所以yield
显然在上面的情况下不起作用。我们将不得不尝试别的东西。
function* generator(numbers) {
yield* numbers.map(x => x + 1);
}
for (let n of generator([1,2,3])) console.log(n);
// 2
// 3
// 4
Again, our for
loop logs each value yield
ed by the generator. Inside our generator, we yield the same result of the numbers.map
call, but this time we use yield*
, which yield by delegation.
同样,我们的for
循环记录yield
了生成器 ed 的每个值。在我们的生成器中,我们产生与numbers.map
调用相同的结果,但这次我们使用yield*
,它由委托产生。
What are we yielding then? Well, Array's have a built-in generator, Array.prototype[Symbol.iterator]
. So at this point, the for
loop is essentially directly stepping thru the generator provided by the Array. Since the array has 3 values, we see 3 logged values.
那我们要屈服什么?好吧,Array 有一个内置的生成器,Array.prototype[Symbol.iterator]
. 所以在这一点上,for
循环本质上是直接通过 Array 提供的生成器。由于数组有 3 个值,我们看到 3 个记录值。
Watchful eyes
警惕的眼神
So we iterate thru numbers
once using Array.prototype.map
but then we iterate thru the intermediate array using the for
loop? Seems like a waste doesn't it?
因此,我们使用循环遍历numbers
一次Array.prototype.map
,然后使用循环遍历中间数组for
?好像很浪费是不是?
Let's look back at your original code though
让我们回顾一下你的原始代码
function *generator() {
let numbers = [1,2,3,4,5];
numbers.map(n => yield (n + 1));
}
for (var n of generator()) {
console.log(n);
}
Notice that your numbers.map
call is pretty meaningless. Array.prototype.map
creates a new array, but your generator doesn't doanything with it. So reallyyou're just using map
to iterate thru the numbers, not because you actually care about the returned value of map
请注意,您的numbers.map
通话毫无意义。Array.prototype.map
创建一个新数组,但您的生成器不会对它做任何事情。所以实际上你只是map
用来遍历数字,而不是因为你实际上关心的返回值map
Say what you mean, mean what you say
说你的意思,说你的意思
OK, so now we know we only really care about iterating thru the numbers. So we'll use iterationthe way JavaScript knows best
好的,现在我们知道我们只关心遍历数字。所以我们将以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
Bingo. No tricky yield*
. No double iteration. No nonsense.
答对了。不难yield*
。没有双重迭代。没有废话。
回答by Joseph
That's because the arrow function is not a generator. If I expand your arrow function, it would look something like:
那是因为箭头函数不是生成器。如果我展开你的箭头函数,它看起来像:
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));
}
回答by ErichBSchulz
Just discovered you can encounter this by accidentally closing your function too early.
刚刚发现您可能会因意外过早关闭函数而遇到此问题。
i.e. one too many }
即一个太多 }
回答by Eric
[1,2,3,4,5].map(function*(v){yield v+1;}).reduce((accumulator, currentValue) => accumulator = [...accumulator].concat([...currentValue]))
explanation...
解释...
[1,2,3,4,5].map(function*(v){yield v+1;})
pack all values into generator resulting
将所有值打包到生成器中
(5)?[Generator, Generator, Generator, Generator, Generator]
(5)?[发电机,发电机,发电机,发电机,发电机]
unpack into flat array
解压成平面阵列
.reduce((accumulator, currentValue) => accumulator = [...accumulator].concat([...currentValue]))
(5)?[2, 3, 4, 5, 6]
(5)?[2, 3, 4, 5, 6]
for normal use
正常使用
[1,2,3,4,5].map(function*(v){yield v+1;}).forEach(v => console.log([...v][0]))
2
3
4
5
6
2
3
4
5
6
[...v][0] is a bit ugly but it is works.
[...v][0] 有点难看,但它是有效的。