Why does for ([] in object);
work fine but [void 0 for ([] in object)]
or (void 0 for ([] in object))
throw a syntax error for invalid left-hand assignment?
For example, I would expect the following code to work, but it doesn't (the assertion isn't even done due to the syntax error):
let (
i = 0,
i开发者_如何学运维terable = {__iterator__:function() { var i = 5; while (i--) yield i; } }
) {
for ([] in iterable) i++;
console.assertEquals([void 0 for ([] in iterable)].length, i);
}
I did a little digging in jsparse.c
of SpiderMonkey (which I assume is the JS parser you're using for 1.8 features?)
The [code for (... in ...)]
format or generator expression uses a different parse function than the standard for ([] in obj)
uses.
Your LHS error is being created here: (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 }
When it sees the [
it finds the Destructuring Expression, and ensures the count of the parser node is at 2.
Interestingly enough [void 0 for ([a,b] in iterator)]
should work, although for reasons I don't care to go digging for, the b
from [a,b]
is always undefined:
js> [[l1,typeof l2] for ([l1,l2] in {a:1, b:2})]
a,undefined,b,undefined
For reference - The standard for([] in {})
uses the following logic to determine the LHS validity:
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
Which seems to mean that versions other than 1.7 don't require 2 left hand values for this syntax. The generator expression might be using older parsing logic. This might be worth submitting as a report to the SpiderMonkey maintainers.
精彩评论