[英]Why is ES6 “yield” a reserved word when called in this context?
I am using node 4.1.1. 我正在使用节点4.1.1。 When I run this code
当我运行此代码时
"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?
当然,如果保留一个关键字,它会在所有上下文中保留,而不仅仅是在箭头函数中使用它?
You can do anything but not everything – Learn to delegate 你可以做任何事情而不是一切 - 学会委派
Let's first look at two examples 我们先来看两个例子
1. yield 产量
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. 我们的
for
循环记录了生成器产生的每个值。 Inside our generator, we have a single yield
call which will yield the result of the numbers.map
call, which is a new Array. 在我们的生成器中,我们有一个
yield
调用,它将产生numbers.map
调用的结果,这是一个新的Array。 Because there is only a single yield, the only logged value is [2,3,4]
因为只有一个产量,所以唯一记录的值是
[2,3,4]
2. yield*
yield*
So yield
obviously won't work in the case above. 因此,在上述情况下,
yield
显然不会起作用。 We'll have to try something else. 我们必须尝试别的东西。
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. 同样,我们
for
循环日志的每个值yield
由发电机编。 Inside our generator, we yield the same result of the numbers.map
call, but this time we use yield*
, which yield by delegation . 在我们的生成器中,我们产生了与
numbers.map
调用相同的结果,但这次我们使用yield*
,它通过委托产生 。
What are we yielding then? 那我们收获的是什么? Well, Array's have a built-in generator,
Array.prototype[Symbol.iterator]
. 好吧,Array有一个内置的生成器,
Array.prototype[Symbol.iterator]
。 So at this point, the for
loop is essentially directly stepping thru the generator provided by the Array. 所以在这一点上,
for
循环基本上直接通过Array提供的生成器步进。 Since the array has 3 values, we see 3 logged values. 由于数组有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? 所以我们使用
Array.prototype.map
迭代numbers
一次但是然后我们使用for
循环遍历中间数组? Seems like a waste doesn't it? 好像浪费不是吗?
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. 请注意,您的
numbers.map
调用非常无意义。 Array.prototype.map
creates a new array, but your generator doesn't do anything with it. Array.prototype.map
创建一个新数组,但您的生成器不会对它执行任何操作。 So really you're just using map
to iterate thru the numbers, not because you actually care about the returned value of 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 iteration the 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*
. 没有棘手的
yield*
。 No double iteration. 没有双重迭代。 No nonsense.
没有废话。
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. 不。因为
temp
不是发电机功能。 The same is applicable to arrow functions as well. 这同样适用于箭头功能。
FWIW, the usage of yield
in an Arrow function is an early error as per the ECMAScript 2015 specification, as per this section , FWIW,根据ECMAScript 2015规范,箭头函数中
yield
的使用是一个早期错误,按照本节的规定 ,
ArrowFunction : ArrowParameters => ConciseBody
ArrowFunction:ArrowParameters => ConciseBody
It is a Syntax Error if ArrowParameters Contains YieldExpression is true .
如果ArrowParameters包含YieldExpression为true ,则为语法错误。
It is a Syntax Error if ConciseBody Contains YieldExpression is true .
如果ConciseBody包含YieldExpression为true ,则为语法错误。
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));
}
[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
2
3
3
4
4
5
五
6
6
[...v][0] is a bit ugly but it is works. [... v] [0]有点丑,但它确实有效。
Just discovered you can encounter this by accidentally closing your function too early. 刚刚发现你可能会因为过早地关闭你的功能而遇到这种情况。
ie one too many }
即太多了
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.