¿Qué hacen las llaves en las sentencias `var {…} =…`?

117

No estoy seguro de si se trata de una sintaxis JS específica de Mozilla, pero a menudo encontré variables que se declaran de esta manera, por ejemplo, en los documentos complementarios del SDK :

var { Hotkey } = require("sdk/hotkeys");

y en varios JavaScript de Chrome ( letse usa una declaración en lugar de var),

let { classes: Cc, interfaces: Ci, results: Cr, utils: Cu }  = Components;

Lo encontré muy confuso pero no puedo encontrar ninguna documentación sobre ambas sintaxis, incluso en MDN .

timdream
fuente
@Blender ¿Cómo buscaría esta estructura en symbolhound.com?
trusktr
1
@trusktr: Un poco tarde: symbolhound.com/…
Blender
La respuesta corta está aquí: stackoverflow.com/a/45909752/203704
Cliff Hall
Estoy bien con la deconstrucción básica. Sin embargo, en este ejemplo también estamos asignando el valor a un nombre de propiedad diferente y esa sintaxis es muy, muy confusa. Es opuesto a la sintaxis de creación de objetos y eso agrega aún más confusión.
Sol

Respuestas:

72

Ambas son características de JavaScript 1.7. El primero son las variables a nivel de bloque :

letle permite declarar variables, limitando su alcance al bloque, declaración o expresión en la que se usa. Esto es diferente a la varpalabra clave, que define una variable globalmente o localmente a una función completa independientemente del alcance del bloque.

El segundo se llama desestructuración :

La asignación de estructura hace posible extraer datos de matrices u objetos utilizando una sintaxis que refleja la construcción de matrices y objetos literales.
...
Una cosa particularmente útil que puede hacer con la asignación de desestructuración es leer una estructura completa en una sola declaración, aunque hay una serie de cosas interesantes que puede hacer con ellas, como se muestra en la sección llena de ejemplos que sigue.

Para aquellos familiarizados con Python, es similar a esta sintaxis:

>>> a, (b, c) = (1, (2, 3))
>>> a, b, c
(1, 2, 3)

El primer fragmento de código es una abreviatura de:

var {Hotkey: Hotkey} = require("sdk/hotkeys");
// Or
var Hotkey = require("sdk/hotkeys").Hotkey;

Puede reescribir el segundo fragmento de código como:

let Cc = Components.classes;
let Ci = Components.interfaces;
let Cr = Components.results;
let Cu = Components.utils;
Licuadora
fuente
2
De mi experimento, parece que var { Hotkey }es equivalente a var { Hotkey: Hotkey }. ¡Gracias por localizar la documentación!
timdream
@timdream: Tenía la sensación de que era algo así, pero ¿en qué se diferencia var Hotkey = require(...).Hotkey? ¿O es solo guardar las pulsaciones de teclas?
Blender
se ve así: - / (jejeje, estos programadores perezosos ...)
timdream
2
Además, hace que todo sea más críptico al usar una sintaxis tan poco común.
trusktr
El segundo es "
Desestructuración de
80

Lo que estás viendo es una tarea de desestructuración. Es una forma de coincidencia de patrones como en Haskell.

Con la asignación de desestructuración, puede extraer valores de objetos y matrices y asignarlos a variables recién declaradas utilizando la sintaxis literal de objeto y matriz. Esto hace que el código sea mucho más conciso.

Por ejemplo:

var ascii = {
    a: 97,
    b: 98,
    c: 99
};

var {a, b, c} = ascii;

El código anterior es equivalente a:

var ascii = {
    a: 97,
    b: 98,
    c: 99
};

var a = ascii.a;
var b = ascii.b;
var c = ascii.c;

De manera similar para las matrices:

var ascii = [97, 98, 99];

var [a, b, c] = ascii;

Esto es equivalente a:

var ascii = [97, 98, 99];

var a = ascii[0];
var b = ascii[1];
var c = ascii[2];

También puede extraer y cambiar el nombre de una propiedad de objeto de la siguiente manera:

var ascii = {
    a: 97,
    b: 98,
    c: 99
};

var {a: A, b: B, c: C} = ascii;

Esto es equivalente a:

var ascii = {
    a: 97,
    b: 98,
    c: 99
};

var A = ascii.a;
var B = ascii.b;
var C = ascii.c;

Eso es todo al respecto.

Aadit M Shah
fuente
12
+1 para los ejemplos de desestructuración de objetos, son realmente útiles. Los ejemplos de MDN solo muestran la desestructuración de matrices.
Blender
@Blender: proporcionan ejemplos de desestructuración de objetos. Observe Bucle entre valores en una matriz de objetos .
Aadit M Shah
Me refiero a la var {a, b, c} = ascii;sintaxis.
Blender
Ese último ejemplo es realmente extraño porque normalmente lo que está a la izquierda del colon es lo que se asigna.
Curtis
1

Esta es una tarea destructiva en Javascript y es parte del estándar ES2015. Desempaqueta o extrae valores de matrices o propiedades de objetos en distintas variables. Por ejemplo: Desestructuración de matrices

var foo = ["one", "two", "three"];
//without destructuring
var one = foo[0];
var two = foo[1];
var three = foo[2];

// con desestructuración var [uno, dos, tres] = foo

Por ejemplo: Desestructuración de objetos

var o = {p: 42, q: verdadero}; var {p, q} = o;

console.log (p); // 42 console.log (q); // cierto

// Asignar nuevos nombres de variable var {p: foo, q: bar} = o;

console.log (foo); // 42 console.log (barra); // cierto

Deeksha Sharma
fuente
0

Hay documentación para la letdeclaración en MDN: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/let

letes similar a varporque limita el alcance de la variable declarada. Te permite declarar una variable dentro de un if(){}bloque (o algún otro bloque) y tener esa variable solo "visible" dentro de ese bloque (JavaScript, hasta ahora, tiene alcance de función y no alcance de bloque como la mayoría de los otros lenguajes). Así que letes básicamente una "solución" para algo con lo que muchas personas tienen problemas. Tenga en cuenta que tihs es una función de JavaScript 1.7.

No he encontrado nada en {Foo}.

Jan Hančič
fuente
Lo siento, pensé que estabas preguntando por ambos ... Mi google-fu me falla cuando se trata de {Foo}: /
Jan Hančič
Yo también: - / Google no indexa {y }.
timdream