2010-03-25 10 views
7

Dlaczego for ([] in object); działa poprawnie, ale [void 0 for ([] in object)] lub (void 0 for ([] in object)) podaje błąd składni w przypadku nieprawidłowego przypisania lewej ręki?Przenoszenie przypisania w wyrażeniach generatora i zrozumienie tablicy

Na przykład, chciałbym się spodziewać następujący kod do pracy, ale nie (twierdzenie nie jest jeszcze zrobione ze względu na błąd składni):

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); 
} 
+1

Domyślam się, że trafiają one w różne reguły gramatyczne: pierwsza z nich NIE jest generatorem (jest to twierdzenie), podczas gdy druga jest. Nie wydaje się, że rozkład jest obsługiwany w tej pozycji. –

+1

@Eli: z jaką wersją JS i silnikiem pracujesz? Destrukturyzacja w pojmowaniu i generatory działają dla mnie w FF 3.6.2/JS 1.8.?, Choć dławi się na "let". – outis

+0

@outis: Oh przepraszam, że brakowało mi nawiasu na końcu tego generatora. To zwykły JS 1.8+. –

Odpowiedz

7

Zrobiłem trochę kopania w jsparse.c z SpiderMonkey (które zakładam jest parser JS używasz do 1,8 funkcje?)

sformatować [code for (... in ...)] lub generator expression używa different parse function niż standard for ([] in obj) zastosowań.

Twój błąd LHS jest bycie created here: (linia jsparse.c 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    } 

Kiedy widzi [ znajdzie Expression rozpad, oraz zapewnia rachubę węzła parsera jest na 2.

Co ciekawe [void 0 for ([a,b] in iterator)] powinny działać, chociaż ze względów nie dbam, aby przejść do kopania The b z [a,b] zawsze jest niezdefiniowany:

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

Dla porównania - Standardowa for([] in {}) używa następującej logiki do ustalenia zasadności 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 

co wydaje się oznaczać, że inne wersje niż 1,7 nie wymagają 2 wartości lewej do tej składni . Wyrażenie generatora może wykorzystywać starszą logikę parsowania. To może być warte przesłania jako raport do opiekunów SpiderMonkey.

+0

Wow, dzięki za wspaniałą odpowiedź! Mam zamiar użyć '[code for ([,] in ...)]' lub '[code for ({} in ...)]' as obejście, dopóki to nie zostanie naprawione. –

+1

@ Eli Gray - Nie ma problemu, fajnie było zagłębić się w SpiderMonkey i dowiedzieć się, jak działa parser JS na tym. :) – gnarf

Powiązane problemy