Tarea de desestructuración de JavaScript

La asignación de desestructuración de JavaScript proporciona una forma rápida y flexible de tomar valores de elementos de matriz y propiedades de objetos y ponerlos en variables.

Introducción

Si quisiera seleccionar elementos de una matriz u objeto antes de la actualización de ES2015 a JavaScript, tendría que seleccionarlos individualmente o usar un bucle.

La especificación ES2015 introdujo la asignación de desestructuración, una forma más rápida de recuperar elementos de matriz o propiedades de objetos en variables.

En este artículo, usaremos la asignación de desestructuración para convertir valores de matrices y objetos en variables. Luego veremos un uso avanzado de la asignación de desestructuración que nos permite establecer valores predeterminados para las variables, capturar entradas no asignadas e intercambiar variables en una línea.

Desestructuración de matrices {#desestructuración de matrices}

Cuando queremos tomar elementos de una matriz y usarlos en variables separadas, generalmente escribimos código como este:

1
2
3
4
let myArray = [1, 2, 3];
let first = myArray[0];
let second = myArray[1];
let third = myArray[2];

Desde la actualización principal de ES2015 a JavaScript, ahora podemos hacer la misma tarea de esta manera:

1
2
let myArray = [1, 2, 3];
let [first, second, third] = myArray;

El segundo ejemplo, más corto, usó la sintaxis de desestructuración de JavaScript en myArray. Cuando desestructuramos una matriz, estamos copiando los valores de sus elementos en variables. La sintaxis de desestructuración de matrices es como la sintaxis de asignación de variables regular (let x = y;). La diferencia es que el lado izquierdo consta de una o más variables en una matriz.

El código anterior creó tres nuevas variables: primera, segunda y tercera. También asignó valores a esas variables: ‘primero’ es igual a 1, ‘segundo’ es igual a 2 y ’tercero’ es igual a 3.

Con esta sintaxis, JavaScript ve que first y 1 tienen el mismo índice en sus respectivas matrices, 0. A las variables se les asignan valores correspondientes a su orden. Siempre que la ubicación coincida entre el lado izquierdo y el derecho, la asignación de desestructuración se realizará en consecuencia.

La sintaxis de desestructuración también funciona con objetos, veamos cómo.

Destrucción de objetos

Antes de que la sintaxis de desestructuración estuviera disponible, si queríamos almacenar las propiedades de un objeto en diferentes variables, escribiríamos un código como este:

1
2
3
4
5
6
7
const foobar = {
    foo: "hello",
    bar: "world"
};

const foo = foobar.foo;
const bar = foobar.bar;

Con la sintaxis de desestructuración, ahora podemos hacer lo mismo rápidamente con menos líneas de código:

1
2
3
4
5
6
const foobar = {
    foo: "hello",
    bar: "world"
};

const { foo, bar } = foobar;

Mientras que los elementos de la matriz se desestructuran por su posición, las propiedades de los objetos se desestructuran por su nombre clave. En el ejemplo anterior, después de declarar el objeto foobar creamos dos variables: foo y bar. A cada variable se le asigna el valor de la propiedad del objeto con el mismo nombre. Por lo tanto foo es "hola" y bar es "mundo".

Nota: La asignación de desestructuración funciona ya sea que declare una variable con var, let o const.

Si prefiere dar un nombre de variable diferente al desestructurar un objeto, podemos hacer un pequeño ajuste a nuestro código:

1
2
3
4
5
6
7
const foobar = {
    foo: "hello",
    bar: "world"
};

const { foo: baz, bar } = foobar;
console.log(baz, bar); // hello world

Con dos puntos, podemos hacer coincidir una propiedad de objeto y dar a la variable creada un nuevo nombre. El código anterior no crea una variable foo. Si intenta usar foo, obtendrá un ReferenceError, lo que indica que no se definió.

Ahora que tenemos los conceptos básicos de la desestructuración de arreglos y objetos, veamos algunos buenos trucos con esta nueva sintaxis. Comenzaremos con nuestra opción para seleccionar valores predeterminados.

Valores predeterminados en variables desestructuradas {#valores predeterminados en variables desestructuradas}

¿Qué sucede si tratamos de desestructurar más variables que el número de elementos de la matriz o las propiedades del objeto? Veamos con un ejemplo rápido:

1
2
3
let [alpha1, alpha2, alpha3] = ['a', 'b'];

console.log(alpha1, alpha2, alpha3);

Nuestra salida será:

1
a b undefined

Las variables no asignadas se establecen en undefined. Si queremos evitar que nuestras variables desestructuradas sean indefinidas, podemos darles un valor predeterminado. Reutilicemos el ejemplo anterior, y por defecto alpha3 a 'c':

1
2
3
let [alpha1, alpha2, alpha3 = 'c'] = ['a', 'b'];

console.log(alpha1, alpha2, alpha3);

Si ejecutamos esto en node o en el navegador, veremos el siguiente resultado en la consola:

1
a b c

Los valores predeterminados se crean usando el operador = cuando creamos una variable. Cuando creamos variables con un valor predeterminado, si hay una coincidencia en el entorno de desestructuración, se sobrescribirá.

Confirmemos que ese es el caso con el siguiente ejemplo, que establece un valor predeterminado en un objeto:

1
2
3
const { prime1 = 1, prime2 } = { prime1: 2, prime2: 3 };

console.log(prime1, prime2);

En el ejemplo anterior, por defecto prime1 es 1. Debe sobrescribirse para que sea 2 ya que hay una propiedad prime1 en el objeto en el lado derecho de la asignación. Ejecutar esto produce:

1
2 3

¡Excelente! Hemos confirmado que los valores predeterminados se sobrescriben cuando hay una coincidencia. Esto también es bueno porque el primer número primo es 2 y no 1.

Los valores predeterminados son útiles cuando tenemos muy pocos valores en la matriz o el objeto. Veamos cómo manejar los casos cuando hay muchos más valores que no necesitan ser variables.

Captura de entradas no asignadas en una asignación desestructurada

A veces queremos seleccionar algunas entradas de una matriz u objeto y capturar los valores restantes que no pusimos en variables individuales. Podemos hacer precisamente eso con el operador ....

Coloquemos el primer elemento de una matriz en una nueva variable, pero mantengamos los otros elementos en una nueva matriz:

1
const [favoriteSnack, ...fruits] = ['chocolate', 'apple', 'banana', 'mango'];

En el código anterior, configuramos favoriteSnack en 'chocolate'. Debido a que usamos el operador ..., frutas es igual a los elementos restantes de la matriz, que es ['manzana', 'plátano', 'mango'].

Nos referimos a las variables creadas con ... en la asignación de desestructuración como el elemento resto. El elemento resto debe ser el último elemento de la asignación de desestructuración.

Como habrás sospechado, también podemos usar el elemento resto en los objetos:

1
2
3
4
5
const { id, ...person } = {
    name: 'Tracy',
    age: 24,
    id: 1020212,
};

Extraemos la propiedad id del objeto en el lado derecho de la asignación de desestructuración en su propia variable. Luego ponemos las propiedades restantes del objeto en una variable persona. En este caso, id sería igual a 1020212 y persona sería igual a { nombre: 'Tracy', edad: 24 }.

Ahora que hemos visto cómo conservar todos los datos, veamos qué tan flexible es la asignación de desestructuración cuando queremos omitir datos.

Valores selectivos en una asignación de desestructuración {#valores selectivos en una asignación de desestructuración}

No tenemos que asignar cada entrada a una variable. Por ejemplo, si solo queremos asignar una variable entre muchas opciones, podemos escribir:

1
2
const [name] = ['Katrin', 'Judy', 'Eva'];
const { nyc: city } = { nyc: 'New York City', ldn: 'London' };

Asignamos name a 'Katrin' de la matriz y city a 'New York City' del objeto. Con los objetos, debido a que hacemos coincidir los nombres de las claves, es trivial seleccionar las propiedades particulares que queremos en las variables. En el ejemplo anterior, ¿cómo podríamos capturar a 'Katrin' y 'Eva' sin tener que capturar también a 'Judy'?

La sintaxis de desestructuración nos permite poner agujeros para valores que no nos interesan. Usemos un agujero para capturar 'Katrin' y 'Eva' de una sola vez:

1
const [name1, , name2] = ['Katrin', 'Judy', 'Eva'];

Tenga en cuenta la brecha en la asignación de variables entre name1 y name2.

Hasta ahora hemos visto cuán flexible puede ser la asignación de desestructuración, aunque solo con valores planos. En JavaScript, las matrices pueden contener matrices y los objetos se pueden anidar con objetos. También podemos tener arreglos con objetos y objetos con arreglos. Veamos cómo la asignación de desestructuración maneja los valores anidados.

Desestructuración de valores anidados {#desestructuración de valores anidados}

Podemos anidar variables de desestructuración para que coincidan con las entradas anidadas de una matriz y un objeto, lo que nos brinda un control detallado de lo que seleccionamos. Considere tener una matriz de matrices. Copiemos el primer elemento de cada matriz interna en su propia variable:

1
2
3
let [[part1], [part2], [part3], [part4]] = [['fee', 'mee'], ['fi', 'li'], ['fo', 'ko'], ['fum', 'plum']];

console.log(part1, part2, part3, part4);

Ejecutar este código mostrará el siguiente resultado:

1
fee fi fo fum

Simplemente envolviendo cada variable en el lado izquierdo con [], JavaScript sabe que queremos el valor dentro de una matriz y no la matriz en sí.

Cuando desestructuramos objetos anidados, tenemos que hacer coincidir la clave del objeto anidado para recuperarlo. Por ejemplo, intentemos capturar algunos detalles de un prisionero en JavaScript:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
const {
    name,
    crimes: {
        yearsToServe
    }
} = {
    name: 'John Doe',
    crimes: {
        charged: ['grand theft auto', 'stealing candy from a baby'],
        yearsToServe: 25
    }
};

console.log(yearsToServe);

Para obtener la propiedad yearsToServe, primero debemos hacer coincidir el objeto crimes anidado. En este caso, el lado derecho tiene una propiedad yearsToServe del objeto crimes establecida en 25. Por lo tanto, a nuestra variable yearsToServe se le asignará un valor de 25.

Tenga en cuenta que no creamos un objeto crímenes en el ejemplo anterior. Creamos dos variables: name y yearsToServe. Aunque debemos hacer coincidir la estructura anidada, JavaScript no crea objetos intermedios.

Lo ha hecho muy bien hasta ahora al cubrir muchas de las capacidades de sintaxis desestructurada. ¡Echemos un vistazo a algunos usos prácticos!

Casos de uso para desestructurar arreglos y objetos {#casos de uso para desestructurar arreglos y objetos}

Hay muchos usos para desestructurar arreglos y objetos, además de los beneficios de las líneas de código. Aquí hay un par de casos comunes en los que la desestructuración mejora la legibilidad de nuestro código:

Bucles for {#bucles for}

Los desarrolladores utilizan la asignación de desestructuración para obtener rápidamente valores de interés de un elemento en un bucle for. Por ejemplo, si quisiera imprimir todas las claves y valores de un objeto, puede escribir lo siguiente:

1
2
3
4
5
const greetings = { en: 'hi', es: 'hola', fr: 'bonjour' };

for (const [key, value] of Object.entries(greetings)) {
    console.log(`${key}: ${value}`);
}

Primero, creamos una variable saludos que almacena cómo decir "hola" en diferentes idiomas. Luego recorremos los valores del objeto usando el método Object.entries() que crea una matriz anidada. Cada propiedad de objeto está representada por una matriz bidimensional, siendo el primer elemento la clave y el segundo elemento su valor. En este caso, Object.entries() crea la siguiente matriz [['en', 'hi'], ['es', 'hola'], ['fr', 'bonjour']].

En nuestro bucle for, desestructuramos las matrices individuales en variables clave y valor. Luego los registramos en la consola. La ejecución de este programa da el siguiente resultado:

1
2
3
en: hi
es: hola
fr: bonjour

Variables de intercambio {#variables de intercambio}

Podemos usar la sintaxis de desestructuración para intercambiar variables sin una variable temporal. Digamos que estás en el trabajo y tomando un descanso. Querías un poco de té, mientras que tu compañero de trabajo quería un poco de café. Desafortunadamente, las bebidas se mezclaron. Si esto estuviera en JavaScript, puede cambiar fácilmente las bebidas usando la sintaxis de desestructuración:

1
2
3
let myCup = 'coffee';
let coworkerCup = 'tea';
[myCup, coworkerCup] = [coworkerCup, myCup];

Ahora myCup tiene 'tea' y coworkerCup tiene 'coffee'. Tenga en cuenta que no teníamos let, const o var al usar la asignación de desestructuración. Como no estamos declarando nuevas variables, debemos omitir esas palabras clave.

Conclusión

Con la asignación de desestructuración, podemos extraer rápidamente valores de matrices u objetos y ponerlos en sus propias variables. JavaScript hace esto haciendo coincidir la posición de la matriz de la variable, o el nombre de la variable con el nombre de la propiedad del objeto.

Hemos visto que podemos asignar valores predeterminados a las variables que estamos creando. También podemos capturar las propiedades restantes de arreglos y objetos usando el operador .... Podemos omitir entradas al tener agujeros, que se indican con comas sin nada entre ellos. Esta sintaxis también es lo suficientemente flexible para desestructurar matrices y objetos anidados.

Proporcionamos un par de lugares ingeniosos para usar la tarea de desestructuración. ¿Dónde los usarás a continuación?