Qual è un’espressione valida sul lato sinistro nella grammatica JavaScript?

Ok, sappiamo tutti quali sono le espressioni valide sul lato sinistro. Tipo.*

Ma, guardando la definizione dello standard ECMA-Script , sono molto confuso:

LeftHandSideExpression : NewExpression CallExpression 

È solo un errore nella definizione o sto ricevendo qualcosa di sbagliato qui? Voglio dire, questo non significa davvero quello

 new Object = 1; // NewExpression AssignmentOperator PrimaryExpression function () { return foo; }() = 1;// CallExpression AssignmentOperator PrimaryExpression 

dovrebbero essere espressioni di assegnazione valide?


* Dalla mia comprensione umile, questo avrebbe molto più senso:

     LeftHandSideExpression : Identifier MemberExpression [ Expression ] MemberExpression . IdentifierName CallExpression [ Expression ] CallExpression . IdentifierName 

    Per rispondere concisamente alla domanda, tutto ciò che è sotto la produzione LeftHandSideExpression è una LeftHandSideExpression valida.


    Penso che la domanda che stai veramente chiedendo sia:

    Cos’è una LeftHandSideExpression valida e anche assegnabile?

    La risposta è tutto ciò che si risolve in un Reference che è un concetto ben definito nelle specifiche. Nel tuo esempio

     new Object = 1; 

    Il new Object è un LeftHandSideExpression valido ma non si risolve in un Reference .

     (new Object).x = 1; 

    Il lato sinistro è un MemberExpression . IdentifierName MemberExpression . IdentifierName che secondo le specifiche del passo finale è:

    Restituisce un valore di tipo Riferimento


    Se lo consideri 2 proprietà separate ha molto più senso.

    1. È un LeftHandSideExpression valido?
    2. È un riferimento valido?

    La proprietà 1 viene determinata nella fase di analisi sintattica e la proprietà 2 viene determinata nella fase di analisi semantica. Controlla 8.7.2 PutValue (V, W) per maggiori dettagli.

    Ecco una spiegazione completa nella specifica stessa:

    8.7 Il tipo di specifica di riferimento

    Il tipo di riferimento viene utilizzato per spiegare il comportamento di tali operatori come delete, typeof e gli operatori di assegnazione. Ad esempio, si prevede che l’operando di sinistra di un compito produca un riferimento. Il comportamento di assegnazione potrebbe, invece, essere spiegato interamente in termini di un’analisi del caso sulla forma sintattica dell’operando di sinistra di un operatore di assegnazione, ma per una difficoltà: le chiamate di funzione sono autorizzate a restituire riferimenti. Questa possibilità è ammessa puramente per il bene degli oggetti ospiti. Nessuna funzione ECMAScript incorporata definita da questa specifica restituisce un riferimento e non vi è alcuna possibilità che una funzione definita dall’utente restituisca un riferimento. (Un altro motivo per non utilizzare un’analisi del caso sintattico è che sarebbe lungo e complicato, influenzando molte parti delle specifiche).


    Dopo aver dato un’occhiata al tuo suggerimento, credo che avrebbe gettato alcune espressioni valide (Nota: non lo condonerò).

     function OuterObj() { this.Name = "Outer"; this.InnerObj = function() { this.Name = "Inner"; } } var obj; (obj = new new OuterObj().InnerObj).Name = "Assigned"; 

    Questo è un caso in cui NewExpression è importante

    Questa è una grammatica JavaScript alternativa che corrisponderà solo a LeftHandSideExpressions valide, ovvero LeftHandSideExpressions che sono effettivamente assegnabili.

     NewExpression : PrimaryExpression new NewExpressionQualifier Arguments new NewExpressionQualifier NewExpressionQualifier : NewExpressionQualifier Qualifier NewExpression CallExpression : NewExpression CallExpressionQualifier Arguments CallExpressionQualifier : CallExpression CallExpressionQualifier Qualifier LeftHandSideExpression : LeftHandSideExpression Qualifier CallExpression Qualifier Identifier ( LeftHandSideExpression ) ( Expression , LeftHandSideExpression ) Qualifier : . IdentifierName [ Expression ] 

    Ogni argomento per il quale la scelta della nuova espressione o call associata è ambigua deve essere associato alla nuova espressione più prossima ansible che altrimenti non avrebbe argomenti corrispondenti. Penso che questo sia uno dei motivi per cui vi è sia una nuova espressione sia un non terminatore MemberExpression nella grammatica di JavaScript.