destrutturazione di oggetti senza var


97

Perché la destrutturazione degli oggetti genera un errore se non ci sono varparole chiave davanti?

{a, b} = {a: 1, b: 2};

lanci SyntaxError: expected expression, got '='

I tre esempi seguenti funzionano senza problemi

var {a, b} = {a: 1, b: 2};
var [c, d] = [1, 2];
    [e, f] = [1, 2];

Domanda bonus: perché non abbiamo bisogno di una vardestrutturazione dell'array?

Mi sono imbattuto nel problema facendo qualcosa di simile

function () {
  var {a, b} = objectReturningFunction();

  // Now a and b are local variables in the function, right?
  // So why can't I assign values to them?

  {a, b} = objectReturningFunction();
}

Risposte:


158

Il problema deriva dagli {...}operatori che hanno più significati in JavaScript.

Quando {appare all'inizio di un'istruzione , rappresenterà sempre un blocco , a cui non è possibile assegnare. Se appare in un secondo momento nell'istruzione come espressione , rappresenterà un oggetto.

Gli varaiuti fanno questa distinzione, dal momento che non può essere seguita da un'istruzione , così come il raggruppamento delle parentesi :

( {a, b} = objectReturningFunction() );

Dai loro documenti: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assignment_without_declaration

Note: le parentesi (...) attorno all'istruzione di assegnazione sono necessarie quando si utilizza l'assegnazione di destrutturazione letterale dell'oggetto senza una dichiarazione.

{a, b} = {a: 1, b: 2} non è una sintassi autonoma valida, poiché {a, b} sul lato sinistro è considerato un blocco e non un oggetto letterale.

Tuttavia, ({a, b} = {a: 1, b: 2}) è valido, così come var {a, b} = {a: 1, b: 2}

La tua espressione (...) deve essere preceduta da un punto e virgola oppure può essere utilizzata per eseguire una funzione nella riga precedente.


Se appare in un secondo momento nell'istruzione come espressione, rappresenterà un oggetto. Ciò significa che non possiamo mai avere l'ambito del blocco all'interno di parentesi di raggruppamento
sharad_kalya

Il suggerimento per raggruppare le parentesi è ottimo.
James Smith

Questa è una conoscenza incredibilmente oscura che mi ha lasciato perplesso. Permette la destrutturazione attraverso l'ambito (beh, più o meno - devi ancora dichiarare le tue variabili, ovviamente). Ma risolve un vincolo dell'uso delle catene Promise mentre è necessario utilizzare più variabili risolte da un passaggio di una catena Promise in un altro, senza creare troppi problemi. Grazie.
Kevin Teljeur

22

Se scrivi Javascript senza punto e virgola , la sintassi "assegnazione senza dichiarazione" dovrebbe essere preceduta da un punto e virgola affinché funzioni in modo prevedibile

let a, b

;({a, b} = objectReturningFunction()) // <-- note the preceding ;

Volevo solo evidenziarlo perché mi ha colto di sorpresa, e si spera di poter risparmiare un po 'di tempo ad altri per capire perché non funziona e / o produce risultati strani con formattatori di codice come prettier.

In effetti, è proprio lì nella risposta accettata (ultima riga dei documenti citati) ma facile da perdere, soprattutto senza vedere un esempio!


1
Si. Un motivo per cui le persone usano i punti e virgola!
jfriend00

0

Ecco un altro modo:

let {} = {a, b} = objectReturningFunction()

Professionisti:

  • Nessuna parentesi necessaria
  • Nessun punto e virgola necessario
  • L'assegnazione extra è un divieto garantito (dato che non stanno succedendo cose strane)

Contro:

  • Sembra un po 'strano, anche se a mio parere non è più strano !(){...}() dell'IIFE .
  • Potrebbe essere fonte di confusione sul motivo per cui è lì. È garantito che sbalordirà le persone al primo incontro, quindi consiglierei di non usarlo come una tantum.

Tipo di Feels Like di IIFE sono più paragonabile a ;({ a, b })quello let {} = { ... }. Bel trucco però. :)
shuckster

@ proto-n, +1, idea molto intelligente. Come ti sei imbattuto in questo?
Pacerier
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.