desestructuración de objetos sin var


97

¿Por qué la desestructuración de objetos arroja un error si no hay una varpalabra clave delante?

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

lanza SyntaxError: expected expression, got '='

Los siguientes tres ejemplos funcionan sin problemas

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

Pregunta adicional: ¿Por qué no necesitamos una vardesestructuración de matrices?

Me encontré con el problema haciendo algo como

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();
}

Respuestas:


158

El problema se debe a que los {...}operadores tienen múltiples significados en JavaScript.

Cuando {aparece al comienzo de una declaración , siempre representará un bloque al que no se puede asignar. Si aparece más adelante en la declaración como expresión , entonces representará un objeto.

Las varayudas hacen esta distinción, ya que no puede ir seguida de una declaración , al igual que la agrupación de paréntesis :

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

De sus documentos: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assignment_without_declaration

Notas: Los paréntesis (...) alrededor de la declaración de asignación son obligatorios cuando se usa la asignación de desestructuración literal de objeto sin una declaración.

{a, b} = {a: 1, b: 2} no es una sintaxis independiente válida, ya que {a, b} en el lado izquierdo se considera un bloque y no un objeto literal.

Sin embargo, ({a, b} = {a: 1, b: 2}) es válido, al igual que var {a, b} = {a: 1, b: 2}

Su expresión (...) debe estar precedida por un punto y coma o puede usarse para ejecutar una función en la línea anterior.


Si aparece más adelante en la declaración como una expresión, entonces representará un objeto. ¿Significa esto que nunca podemos tener un alcance de bloque dentro del paréntesis de agrupación?
sharad_kalya

La sugerencia del paréntesis de agrupación es excelente.
James Smith

Este es un conocimiento brillantemente oscuro que me dejó perplejo. Permite la desestructuración a través del alcance (bueno, más o menos, todavía necesita declarar sus variables, por supuesto). Pero resuelve una restricción de usar cadenas de promesas mientras se necesita usar múltiples variables resueltas de un paso de una cadena de promesas en otro, sin crear demasiado desorden. Gracias.
Kevin Teljeur

22

Si escribe Javascript sin punto y coma , entonces la sintaxis de 'asignación sin declaración' debe ir precedida de un punto y coma para que funcione de manera predecible

let a, b

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

Solo quería resaltar esto, ya que me atrapó, y espero que pueda ahorrarles a otros algo de tiempo averiguando por qué no funciona y / o produce resultados extraños con formateadores de código como prettier .

De hecho, en realidad está allí en la respuesta aceptada (última línea de los documentos citados) pero es fácil pasarla por alto, ¡especialmente sin ver un ejemplo!


1
Si. ¡Una razón para que la gente use punto y coma!
jfriend00

0

He aquí otra forma:

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

Pros:

  • No se necesitan paréntesis
  • No se necesitan puntos y comas

Contras:

  • Parece un poco extraño, aunque en mi opinión no es más extraño que el !(){...}() IIFE
  • Puede ser confuso en cuanto a por qué está ahí

Tipo de se siente como de IIFE son más comparables a los ;({ a, b })de let {} = { ... }. Buen truco. :)
shuckster

@ proto-n, +1, idea muy inteligente. ¿Cómo se encontró con esto?
Pacerier
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.