生成器表达式和数组理解中的解构赋值

Eli*_*rey 7 javascript

为什么for ([] in object);做工精细,但[void 0 for ([] in object)]还是(void 0 for ([] in object))抛出无效左手分配的语法错误?

例如,我希望以下代码可以工作,但它没有(由于语法错误,甚至没有完成断言):

let (
  i = 0,
  iterable = {__iterator__:function() { var i = 5; while (i--) yield i; } }
) {
  for ([] in iterable) i++;
  console.assertEquals([void 0 for ([] in iterable)].length, i);
}
Run Code Online (Sandbox Code Playgroud)

gna*_*arf 7

jsparse.c对SpiderMonkey 进行了一些挖掘(我假设你是用于1.8功能的JS解析器?)

[code for (... in ...)]格式或发电机表达使用不同parse函数标准for ([] in obj)的用途.

您的LHS错误正在此处创建:(jsparse.c line 4200)

4194           case TOK_LB:
4195           case TOK_LC:
4196             pn3 = DestructuringExpr(cx, &data, tc, tt);
4197             if (!pn3)
4198                 return NULL;
4199 
4200             if (pn3->pn_type != TOK_RB || pn3->pn_count != 2) {
4201                 js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
4202                                             JSMSG_BAD_FOR_LEFTSIDE);
4203                 return NULL;
4204             }
Run Code Online (Sandbox Code Playgroud)

当它看到[它找到Destructuring Expression时,并确保解析器节点的计数为2.

有趣的是[void 0 for ([a,b] in iterator)]应该工作,虽然原因我不在乎去挖掘中,b[a,b]总是不确定的:

js> [[l1,typeof l2] for ([l1,l2] in {a:1, b:2})]
a,undefined,b,undefined
Run Code Online (Sandbox Code Playgroud)

供参考 - 该标准for([] in {})使用以下逻辑来确定LHS有效性:

2775 #if JS_HAS_DESTRUCTURING
2776                    ((JSVERSION_NUMBER(cx) == JSVERSION_1_7 &&
2777                      pn->pn_op == JSOP_FORIN)
2778                     ? (pn1->pn_type != TOK_RB || pn1->pn_count != 2)
2779                     : (pn1->pn_type != TOK_RB && pn1->pn_type != TOK_RC)) &&
2780 #endif
Run Code Online (Sandbox Code Playgroud)

这似乎意味着1.7以外的版本不需要2个左手值用于此语法.生成器表达式可能使用较旧的解析逻辑.这可能值得作为报告提交给SpiderMonkey维护者.