javascript SyntaxError:意外标识符(ES6 中的生成器)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20834113/
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
SyntaxError: Unexpected Identifier (Generators in ES6)
提问by Alix Axel
I came up with this simple experiment after reading the documentation on generators from MDN:
在阅读了MDN 中关于生成器的文档后,我想出了这个简单的实验:
var nodes = {
type: 'root',
value: [
{ type: 'char', value: 'a' },
{ type: 'char', value: 'b' },
{ type: 'char', value: 'c' },
],
};
function* recursiveGenerator(node) {
if (node.type === 'root') {
node.value.forEach(function (subnode) {
for (var suffix of recursiveGenerator(subnode)) {
yield suffix;
}
});
}
else {
yield node.value;
}
}
for (generated of recursiveGenerator(nodes)) {
console.log(generated);
}
Running it on node.js v0.11.9 with the --harmony
flag set produces the following error:
在--harmony
设置了标志的node.js v0.11.9 上运行它会产生以下错误:
alix@900X4C:~$ node --version
v0.11.9
alix@900X4C:~$ node --harmony test.js
/home/alix/test.js:14
yield suffix;
^^^^^^
SyntaxError: Unexpected identifier
I also tried using for ... in ...
and the let
keyword instead of var
, but without any success.
我也尝试使用for ... in ...
andlet
关键字代替var
,但没有成功。
I don't understand what yield*
does exactly, but if I use it within the for
loop I get instead:
我不明白究竟yield*
是什么,但如果我在for
循环中使用它,我会得到:
alix@900X4C:~$ node --harmony test.js
/home/alix/test.js:14
yield* suffix;
^
ReferenceError: yield is not defined
If I replace the yield in the for with console.log()
it outputs a
, b
and c
. What am I doing wrong?
如果我将 for 中的 yield 替换为console.log()
它的输出a
,b
和c
. 我究竟做错了什么?
Edit
编辑
Here's a minimalistic generator, showing that node.js knows what to do with generators:
这是一个简约的生成器,表明 node.js 知道如何处理生成器:
function* alpha() {
yield 'a';
yield 'b';
yield 'c';
}
for (var suffix of alpha()) {
console.log(suffix);
}
Output:
输出:
alix@900X4C:~$ node --harmony y.js
a
b
c
Solution (thanks @Andrew)
解决方案(感谢@Andrew)
function* recursiveGenerator(node) {
if (node.type === 'root') {
for (var i = 0; i < node.value.length; ++i) {
var subnode = node.value[i];
for (var suffix of recursiveGenerator(subnode)) {
yield suffix;
}
}
}
else {
yield node.value;
}
}
for (generated of recursiveGenerator(nodes)) {
console.log(generated);
}
回答by vkurchatkin
Summarizing the comments: you can't use yield
inside a regularfunction, so you can't use yield
with forEach
. Here an example of "generatorized" foreach:
总结评论:您不能yield
在常规函数中使用,因此不能使用yield
with forEach
。这是“生成”foreach 的示例:
function * foreach (arr, fn) {
var i
for (i = 0; i < arr.length; i++) {
yield * fn(arr[i])
}
}
function * gen (number) {
yield number + 1
yield number + 2
yield number + 3
}
function * other () {
yield * foreach([1, 2, 3], gen)
}
for (var i of other()) {
console.log(i)
}
UPDATEAlso the original problem can be solved quite elegantly using such a helper:
更新也可以使用这样的助手非常优雅地解决原始问题:
var nodes = {
type: 'root',
value: [
{ type: 'char', value: 'a' },
{ type: 'char', value: 'b' },
{ type: 'root', value: [
{ type: 'char', value: 'c' },
{ type: 'char', value: 'd' },
{ type: 'char', value: 'e' },
]
},
],
}
function * foreach (arr, fn) {
var i
for (i = 0; i < arr.length; i++) {
yield * fn(arr[i])
}
}
function * value (val) {
yield val
}
function * recursiveGenerator(node) {
yield * node.type === 'root' ? foreach(node.value, recursiveGenerator) : value(node.value)
}
for (var generated of recursiveGenerator(nodes)) {
console.log(generated);
}
So the generator itself becomes a one-liner!
所以发电机本身就变成了单线!
回答by nico
You've found your solution, but just for the record here is another example a little different that print the types of all nodes in the tree (I added some deepness and vars)
您已经找到了您的解决方案,但只是为了记录,这里是另一个稍微不同的示例,它打印树中所有节点的类型(我添加了一些深度和变量)
var nodes = {
type: 'root',
value: [
{ type: 'char', value: 'a' },
{ type: 'char', value: 'b' },
{ type: 'char', value: [{type: 'int', value: 'c'}] },
],
};
var flattenTree = function* (root) {
yield root.type;
var subvalues = root.value;
for(var i in subvalues) {
var gen = flattenTree(subvalues[i]);
val = gen.next();
while(!val.done) {
if(val.value != undefined)
yield val.value;
val = gen.next();
}
}
}
var printTree = function() {
console.log("begin tree");
var generator = flattenTree(nodes);
var next = generator.next();
while(!next.done) {
console.log(next);
next = generator.next();
}
console.log("finish tree");
}
printTree();
Outputs:
输出:
~/workspace/tmp$ ../node/node --harmony test-gen.js
begin tree
{ value: 'root', done: false }
{ value: 'char', done: false }
{ value: 'char', done: false }
{ value: 'char', done: false }
{ value: 'int', done: false }
finish tree