Como destructurar objetos con JavaScript y no volver a hacer validaciones de propiedades
Tags: javascript, ecmascript6, destructuring
Published: 2020-03-31 00:04:43

Una de las cosas que mas me gusta de JavaScript es su manejo de objetos. Ademas dada la tendencia de usar JSON en las API, el paso entre obtener información de un servicio y usarlo como objeto en tu código es casi natural. Aunque como todo en la vida usar objetos tiene sus pros y sus contras. Una de las dificultades que encuentro frecuentemente al traer información desde una API es que alguna propiedad falte, para evitar que esto cause algún error inesperado, es una buena practica validar que las propiedades existan, pero hacer estas validaciones puramente mediante condicionales puede resultar engorroso y varias veces bajar el rendimiento de nuestro código. Por un tiempo tuve ese dilema, validar y sacrificar rendimiento o no validad y esperar a que siempre recibiera la información pero gracias a unos compañeros de trabajo aprendi sobre la destructuración.
La destructuración nos sirve primero para poder traer valores y recorrer objetos de una forma simple. Y segundo, en caso necesario, para poder pasar valores por defecto a propiedades que llegaran a ser inexsitentes dentro de un objeto. Ademas algo que me gusta mucho de la destructuración es que puede ir tan profundamente dentro de un objeto como lo necesitemos.
Para entender cómo funciona la destructuración, primero vamos a crear un objeto. Empecemos con algo simple, un objeto persona que tenga tres propiedades: "nombre", "edad" y "sexo".
```js
const persona = {
  nombre: "Emmanuelle",
  edad: 34,
  sexo: "hombre",
};
```
La forma más básica para usar ese objeto es acceder directamente a  sus propiedades de la siguiente forma: persona.nombre, persona.edad o persona.sexo pero tenemos varios inconvenientes aquí, el primero, como ya hemos dicho no estamos seguros de que la propiedad exista pero ademas hay un inconveniente que esta ligado a que es engorroso siempre tener que escribir el nombre del objeto el punto y su propiedad. Para ello, la destructuración también nos va a ayudar. Ejemplo:
```js
const {
  nombre,
  edad,
  sexo,
} = persona;
// Lo anterior es equivalente a hacer lo siguiente
/*
 * const nombre = persona.nombre;
 * const edad = persona.edad;
 * const sexo = persona.sexo;
 */
```
Lo anterior es equivalente a hacer lo que se muestra en los comentarios. Es decir, nos extrae las propiedades indicadas dentro de las llaves del objeto persona y las asigna a constantes con el nombre de las propiedades. Así si quiero saber la edad de la persona solo tengo que llamar a edad y listo. Igual para las demás propiedades. Lo anterior ya nos permite simplificar nuestro código, y escribir menos cada ves que necesitemos el valor de cierta propiedad, pero vamos a seguir teniendo un problema. Aún no sabemos si las propiedades existen o no. Por ejemplo, si quisiera acceder a la propiedad estatura del objeto persona, de forma clásica accedería de la siguiente forma persona.estatura pero esto nos puede causar un error, ya que intentamos acceder a una propiedad que no existe. Para evitar esto, y para evitar condicionales por todo nuestro código, podemos hacer lo siguiente al momento de destructurar:
```js
const {
  nombre = "",
  edad = -1,
  sexo = "",
  estatura = 0,
} = persona;
// El valor de nombre es "Emmanuelle"
// el valor de estatura es 0 sin importar que no se encuentre en el objeto original
```
Lo anterior nos permite declarar un valor por defecto, es decir, si la propiedad no existe, JavaScript declarará la constante y le asignara ese valor, evitando así un error de referencia, es decir: si la propiedad existe, la conserva, sino existe, toma el valor por defecto y la declara.
Con lo que hemos visto hasta ahora, podemos simplificar nuestro código y ademas evitar tener validaciones por todo nuestro código. Pero vamos mas allá y que es normal encontrar objetos más complejos. En realidad encontrar objetos planos o de un solo nivel no es la norma y regularmente encontramos objetos de más de un nivel como vemos a continuación:
```js
const persona = {
  nombre: "Emmanuelle",
  edad: 34,
  sexo: "hombre",
  cabello: {
    tipo: "quebrado",
    color: "negro",
  },
};
```
En el caso anterior podemos hacer una destructuración anidada:
```js
const {
    nombre = "",
    edad = -1,
    sexo = "",
    cabello: { tipo = "", color = "" } = {},
    estatura = 0,
} = persona;
```
Es importante mencionar que en la destructuración anterior no es posible acceder a la variable cabello pero sí podemos acceder a tipo  o color directamente.
Si quisiéramos acceder a la variable cabello, deberíamos hacer la destructuración de la siguiente forma:
```js
const {
    nombre = "",
    edad = -1,
    sexo = "",
    cabello = {
        tipo: "",
        color: "",
    },
    estatura = 0,
} = persona;
```
Esta otra forma de hacer la destructuración nos permite conservar el objeto cabello y su estructura base pero no olvidemos que aquí lo que perdemos es la validación interna del objeto, por lo tanto, si existe cabello pero no existe color dentro de este, JavaScript no hará ninguna validación de color. Yo personalmente recomiendo usar el primer método ya que hace más sentido con el propósito de validar cada propiedad. Pero dependerá de tu proyecto en específico y de tu forma de trabajo o del de tu equipo.
Por último, voy a dejar un ejemplo de como hacer la destructuración con más niveles.
```js
const persona = {
    nombre: "Emmanuelle",
    edad: 34,
    sexo: "hombre",
    cabello: {
        tipo: "quebrado",
    },
};
const {
    nombre = "",
    edad = -1,
    sexo = "",
    cabello: { tipo = "", color = "" },
    estatura = 0,
    ropa: { accesorios: { lentes = true, gorra = false } } = {
        accesorios: {},
    },
} = persona;
```
Las dos cosas a resaltar en este ejemplo, es que vamos a acceder directamente a las variables lentes y gorra, ademas las propiedades ropa y accesorios no existen. El segundo punto a resaltar en esta destructuración, es que es indispensable crear un objeto accesorios por defecto ya que de no hacerlo JavaScript nos mandara un error de referencia ya que accesorios no existe.

__UPDATE: Gracias a [@jmz12](https://medium.com/@jmz12)__

Como bien lo menciona [@jmz12](https://medium.com/@jmz12) en su comentario de en Medium, ademas de hacer validaciones como ya hemos visto, podemos renombrar con la siguiente estructura:
```js
const persona {
    nombre: "Emmanuelle"
};
const {
    nombre: nombreDePila
} = persona;
```
De esta forma, tendríamos que acceder a `nombreDePila` ya que es el nombre con el que declaramos la variable.