La sintaxis de desestructuración es una funcionalidad fascinante que vino junto con ES6. Es una expresión de JavaScript que permite desempacar valores de arreglos o propiedades de objetos en distintas variables. Es decir, podemos extraer datos de arreglos y objectos y asignarlos a variables.

¿Por qué es esto necesario?

Imagina que queremos extraer datos de un arreglo. Anteriormente, ¿cómo se haría esto?

let introduccion = ["Hola", "Yo" , "soy", "Sarah"];
let saludo = introduccion[0];
let nombre = introduccion[3];

console.log(saludo); // "Hola"
console.log(nombre); // "Sarah"

Podemos ver que cuando queremos extraer datos de un arreglo, tenemos que hacer lo mismo una y otra vez.

La desestructuración de ES6 facilita la extracción de estos datos. ¿De qué forma? Primero, discutiremos sobre la desestructuración con arreglos. Luego pasaremos a la desestructuración de objetos.

Empecemos.

Desestructuración Básica de Arreglos

Si queremos extraer datos de un arreglo, es bastante sencillo usando la sintaxis de desestructuración.

Tomando como referencia el primer ejemplo. En lugar de pasar por ese proceso repetitivo, haríamos esto:

let introduccion = ["Hola", "Yo" , "soy", "Sarah"];;
let [saludo, pronombre] = introduccion;

console.log(saludo); // "Hola"
console.log(pronombre); // "Yo"

También podemos lo siguiente, y conseguir el mismo resultado:

let [saludo, pronombre] = ["Hola", "Yo" , "soy", "Sarah"];

console.log(saludo); // "Hola"
console.log(pronombre); // "Yo"

Declarando Variables antes de la Asignación

Las variables se pueden declarar antes de ser asignadas de esta manera:

let saludo, pronombre;
[saludo, pronombre] = ["Hola", "Yo" , "soy", "Sarah"];

console.log(saludo); // "Hola"
console.log(pronombre); // "Yo"

Observa que las variables se establecen de izquierda a derecha. Así que la primera variable obtiene el primer elemento del arreglo, la segunda variable obtiene el segundo elemento, y así sucesivamente.

Omitiendo elementos en un Arreglo

¿Qué pasa si queremos obtener el primer y último elemento de nuestro arreglo en lugar del primero y el segundo, y queremos asignar solo dos variables? Esto también se puede hacer. Fíjate en el siguiente ejemplo:

let [saludo,,,nombre] = ["Hola", "Yo" , "soy", "Sarah"];

console.log(saludo); // "Hola"
console.log(nombre); // "Sarah"

¿Qué acaba de suceder?

Pon atención al lado izquierdo de la asignación de variables del arreglo. Observa que en lugar de tener solo una coma, tenemos tres. El separador de coma se utiliza para omitir valores en un arreglo. Por lo que, si deseas omitir un elemento en un arreglo, usa comas.

Veamos otro ejemplo. Si queremos saltar el primer y tercer elemento de la lista. ¿Cómo lo haríamos?

let [,pronombre,,nombre] = ["Hola", "Yo" , "soy", "Sarah"];

console.log(pronombre); // "Yo"
console.log(nombre); // "Sarah"

Como ves, el separador de comas es el que hace la magia. Entonces, si queremos omitir todos los elementos, simplemente hacemos esto:

let [,,,,] = ["Hola", "Yo" , "soy", "Sarah"];

Asignando el resto de un arreglo


¿Qué sucede si queremos asignar parte del arreglo a variables y el resto de elementos de dicho arreglo a otra variable en particular? En ese caso, haríamos esto:

let [saludo, ...introduccion] = ["Hola", "Yo" , "soy", "Sarah"];

console.log(saludo); // "Hola"
console.log(introduccion); // ["Yo", "soy", "Sarah"]

Utilizando este patrón, puedes desempacar y asignar la parte restante de un arreglo a una variable.

Desestructuración con Funciones

También podemos extraer datos de un arreglo devuelto por una función. Digamos que tenemos una función que devuelve un arreglo como el del siguiente ejemplo:

function obtenerArreglo() {
    return ["Hola", "Yo" , "soy", "Sarah"];
} 

let [saludo, pronombre] = obtenerArreglo();

console.log(saludo); // "Hello"
console.log(pronombre); // "I"

Como puedes observar, obtenemos los mismos resultados.

Usando Valores Predeterminados

Los valores predeterminados se pueden asignar a las variables en caso de que el valor extraído del arreglo sea undefined:

let [saludo = "hey", nombre = "Sarah"] = ["Hola"];

console.log(greeting); // "Hola"
console.log(name); // "Sarah"

Por lo tanto, nombre se vuelve "Sarah" porque no está definido en el arreglo.

Intercambiando Valores mediante Desestructuración

Una cosa más. Podemos usar la desestructuración para intercambiar los valores de las variables:

let a = 3;
let b = 6;

[a, b] = [b, a];

console.log(a); // 6
console.log(b); // 3

A continuación, aprenderemos sobre la Desestructuración de Objetos.

Desestructuración de Objetos

Primero, veamos por qué es necesaria la desestructuración de objetos.

Digamos que queremos extraer datos de un objeto y asignarlos a nuevas variables. Antes de ES6, ¿cómo se haría esto?

let persona = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    trabajo: "Desarrollador"
};

let nombre = persona.nombre;
let pais = persona.pais;
let trabajo = persona.trabajo;

console.log(nombre); // "Sarah"
console.log(pais); // "Nigeria"
console.log(trabajo); // "Desarrollador"

Observa lo tedioso que es extraer todos los datos. Tenemos que hacer lo mismo repetidamente. Por suerte, la desestructuración de ES6 provee una solución. Saltemos directamente a ella.

Desestructuración Básica de Objetos

Repitamos el ejemplo anterior con ES6. En lugar de asignar valores uno por uno, podemos usar el objeto de la izquierda para extraer los datos:

let persona = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    trabajo: "Desarrollador"
};

let {nombre, pais, trabajo} = persona;

console.log(nombre); // "Sarah"
console.log(pais); // "Nigeria"
console.log(trabajo); // "Desarrollador"

Obtendrás los mismos resultados. También es válido asignar variables a un objeto que no ha sido declarado:

let {nombre, pais, trabajo} = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    trabajo: "Desarrollador"
};

console.log(nombre); // "Sarah"
console.log(pais); // "Nigeria"
console.log(trabajo); // "Desarrollador"

Declarando Variables antes de ser asignadas

Las variables en los objetos se pueden declarar antes de asignarlas con desestructuración. Probemos eso:

let persona = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    trabajo: "Desarrollador"
}; 

let nombre, pais, trabajo;

{nombre, pais, trabajo} = persona;

console.log(nombre); // Error : "Unexpected token ="

Espera, ¿qué acaba de pasar? Oh, nos olvidamos de agregar () antes de las llaves.

Los paréntesis  ( ) alrededor de la asignación es una sintaxis requerida cuando se usa la desestructuración literal de un objeto sin una declaración. Esto se debe a que {} en el lado izquierdo se considera un bloque y no un objeto literal. Aquí te muestro la forma correcta de hacerlo:

let persona = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    trabajo: "Desarrollador"
}; 

let nombre, pais, trabajo;

({nombre, pais, trabajo} = persona);

console.log(nombre); // "Sarah"
console.log(trabajo); // "Desarrollador"

También es importante tener en cuenta que al usar esta sintaxis, los paréntesis () deben ir precedido de un punto y coma. De lo contrario, podría usarse para ejecutar una función de la línea anterior.

Observa como las variables del objeto en el lado izquierdo deben tener el mismo nombre que una clave de propiedad en el objeto persona. Si los nombres son diferentes, obtendremos undefined:

let persona = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    trabajo: "Desarrollador"
};

let {nombre, amigos, trabajo} = persona;

console.log(nombre); // "Sarah"
console.log(amigos); // undefined

Pero si queremos usar un nuevo nombre de variable, bueno, también podemos hacerlo.

Usando un nuevo Nombre de Variable

Si queremos asignar valores de un objeto a una nueva variable en lugar de usar el nombre de la propiedad, podemos hacer esto:

let persona = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    trabajo: "Desarrollador"
};

let {nombre: foo, trabajo: bar} = persona;

console.log(foo); // "Sarah"
console.log(bar); // "Desarrollador"

Entonces, los valores extraídos son pasados a las nuevas variables foo y bar.

Usando Valores Predeterminados

Los valores predeterminados también se pueden usar en la desestructuración de objetos, en el caso de que una variable del objeto que se quiere extraer datos esté undefined:

let persona = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    trabajo: "Desarrollador"
};

let {nombre = "miNombre", amiga = "Annie"} = persona;

console.log(nombre); // "Sarah"
console.log(amiga); // "Annie"

Entonces, si el valor no es indefinido (undefined), la variable almacena el valor extraído del objeto como en el caso de nombre. De lo contrario, usará el valor predeterminado como lo hizo con amiga.

También podemos establecer valores predeterminados cuando asignamos valores a una nueva variable:

let persona = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    trabajo: "Desarrollador"
};

let {name: foo = "miNombre", amiga: bar = "Annie"} = persona;

console.log(foo); // "Sarah"
console.log(bar); // "Annie"

Aquí nombre se extrajo de persona y se asignó a una variable diferente. amiga, por otro lado, estaba undefined en persona, por lo que a la nueva variable bar  se le asignó el valor predeterminado.

Nombre de Propiedad Calculado

El nombre de propiedad calculado es otra funcionalidad de objectos literales que también funciona al desestructurar. Puedes especificar el nombre de una propiedad a través de una expresión si la pones entre corchetes:

let prop = "nombre";

let {[prop] : foo} = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    trabajo: "Desarrollador"
};

console.log(foo); // "Sarah"

Combinando Arreglos con Objetos

Las arreglos también se pueden usar con objetos en la desestructuración de objetos:

let persona = {
    nombre: "Sarah", 
    pais: "Nigeria", 
    amigas: ["Annie", "Becky"],
};

let {nombre: foo, amigas: bar} = persona;

console.log(foo); // "Sarah"
console.log(bar); // ["Annie", "Becky"]

Anidamiento en la Desestructuración de Objetos

Los objetos también se pueden anidar al desestructurar:

let persona = {
    nombre: "Sarah",
    lugar: {
        pais: "Nigeria", 
        ciudad: "Lagos" 
    }, 
    amigas : ["Annie", "Becky"]
};

let {
  nombre: foo,
  lugar: { pais: bar, ciudad: x },
} = persona;

console.log(foo); // "Sarah"
console.log(bar); // "Nigeria"

Resto (...rest) en la Desestructuración de Objetos

La sintaxis de resto también se puede utilizar para recopilar claves de propiedad que aún no han sido asignadas durante la desestructuración. Dichas claves y sus valores se copian en un nuevo objeto:

let persona = {
  nombre: "Sarah",
  pais: "Nigeria",
  trabajo: "Desarrollador",
  amigas: ["Annie", "Becky"],
};

let { nombre, amigas, ...otras } = persona;

console.log(nombre); // "Sarah"
console.log(amigas); // ["Annie", "Becky"]
console.log(otras); // {pais: "Nigeria", trabajo: "Desarrollador"}

Aquí, las propiedades restantes cuyas claves no formaban parte de los nombres de variable enumerados se asignaron a la variable otras. La sintaxis de resto (rest) en el ejemplo es ...otras. Cuyo nombre otras se puede cambiar por cualquiera de tu preferencia.

Una última cosa – veamos cómo se puede usar la Desestructuración de Objetos en funciones.

Desestructuración de Objetos y Funciones

La Desestructuración de Objetos se puede utilizar para asignar parámetros a funciones:

function persona({ nombre: x, trabajo: y } = {}) {
  console.log(x);
}

persona({ nombre: "Michelle" }); // "Michelle"
persona(); // undefined
persona(amiga); // Error : amiga is not defined

Observa los {} en el lado derecho de los parámetros del objecto. Nos permite llamar a la función sin pasar ningún argumento. Por eso recibimos undefined. Si lo eliminamos, obtendremos un mensaje de error.

También podemos asignar valores predeterminados a los parámetros:

function person({ nombre: x = "Sarah", trabajo: y = "Desarrollador" } = {}) {
  console.log(x);
}

person({ nombre }); // "Sarah"

Como hemos podido ver, se pueden hacer un montón de cosas con la Desestructuración de Arreglos y Objectos.

Gracias por leer. :)

Traducido del artículo de Sarah Chima Atuonwu - How to Use Array and Object Destructuring in JavaScript.