10 trucos y optimizaciones de código con JavaScript para 2021😎
Tags: javascript, webdev, frontend, spanish
Published: 2021-03-29 13:51:01

#**Índice**   
1. [**Introducción**](#id1)
2. [**Convertir string a number**](#id2)
3. [**Convertir number a string**](#id3)
4. [**Operador ternario o if abreviado**](#id4)
5. [**Operadores de cortocircuito**](#id5)
6. [**Nullish coalescing operator**](#id6)
7. [**Optional Chaining**](#id7)
8. [**Obtener valores únicos con Set**](#id8)
9. [**includes para una condición multiple**](#id9)
10. [**Potencias**](#id10)
11. [**Conclusiones**](#id11)
12. [**Referencias**](#id12)

## **1. Introducción**<a name="id1"></a> 
JavaScript cumplio 25 años recientemente y es **ASOMBROSO** como con el paso del tiempo este hermoso lenguaje de programación creció y evoluciono para implementarse en diferentes campos del desarrollo de software; así mismo la sintaxis mejoró bastante y considero importante conocer ciertos trucos de optimización a considerar para nuestros desarrollos en este 2021.

## **2. Convertir string a number**<a name="id2"></a> 
Tradicionalmente para convertir un `string` a un `number` se usaban los métodos `parseInt()` y `parseFloat()` para un entero y un decimal respectivamente, a continuación un ejemplo:

```javascript
// De string a entero
const numero = "159";
console.log(numero); // "159"
console.log(parseInt(numero,10)); // 159
```

```javascript
// De string a decimal
const numeroDecimal = "236.986";
console.log(numeroDecimal); //"236.986"
console.log(parseFloat(numeroDecimal,10)); //236.986
```

Ambos métodos funcionan muy bien, pero existe una manera más resumida para lograr a los mismos resultados anteponiendo el operador `+`.

```javascript
// De string a entero
const numero = "159";
console.log(numero); //"159"
console.log(+numero); // 159
```

```javascript
// De string a decimal
const numeroDecimal = "236.986";
console.log(numeroDecimal); //"236.986"
console.log(+numeroDecimal); //236.986
```

También es posible usar el constructor del objeto `Number` de la siguiente manera: 

```js
const numero = "159";
console.log(numero); // "159"
console.log(Number(numero)); // 159
```

De igual forma este método funciona con números decimales: 

```js
const numero = "236.986";
console.log(numero); // "236.986"
console.log(Number(numero)); // 236.986
```

## **3. Convertir number a string**<a name="id3"></a> 
Para convertir un `number` a un `string` se puede usar el método `toString()` de la siguiente manera:

```javascript
const edad = 15;
console.log(typeof edad); //number
console.log(typeof edad.toString()); //string
```
Podemos llegar al mismo resultado concatenando un `number` con un `string` vacio,

```javascript
const edad = 15;
console.log(typeof edad); //number
console.log(typeof (edad + '')); //string
```
¡Bastante sencillo!

## **4. Operador ternario o if abreviado**<a name="id4"></a> 
Este operador puede resumir en una sola línea de código un `if` tradicional.
En vez de esto:

```js
const nota = 80;

if(nota>=51){
  console.log("Aprovado");
}else{
  console.log("Reprobado");
}
//salida: Aprobado
```
Podriamos hacer esto:

```js
const nota = 80;
const res = (nota>=51) ? console.log("Aprovado"): console.log("Reprobado")
//salida: Aprobado
```
**Consideraciones acerca del operador ternario o if abreviado:**
* Se debe crear una variable con la condición a evaluar.
* Lo que venga a continuación del operador `?` se evalua si la condición es verdadera.
* Lo que venga a continuación del operador `:` se evalua si la condicón es falsa, como si fuera una sentencia `else`
* El operador `:` es obligatorio escribirlo aunque no lo necesitemos, si este es el caso se acostumbra devolver `null` como se muestra en el siguiente ejemplo.

```js
const nombre = "Cris";
if(nombre === "Cris"){
  console.log(`Hola, soy ${nombre}`);
}
//salida: Hola soy Cris

const res = (nombre === "Cris") ?  console.log(`Hola, soy ${nombre}`): null
//salida: Hola soy Cris
```

## **5. Operadores de cortocircuito**<a name="id5"></a> 
Los operadores de cortocircuito, al igual que un `if` o un operador ternario, evalúan condiciones de una manera más eficiente.
### **Operador `&&`**
El operador de cortocircuito `&&` actúa como un `if` simple (sin else). Si y solo si la condición se evalúa como `true` entonces se ejecuta, caso contrario ignora el código. 

#### **Sintaxis**
```js
expr1 && expr2
```
> *Sí `expr1` evalúa como `true` entonces se ejecuta `expr2`*
> *Sí `expr1` evalúa como `false` entonces NO se ejecuta ninguna de las expresiones, la línea de código es ignorada por el interprete de javascript.*
> *Sí `expr1` contiene un `null` o un `undefined` regresará `null` o `undefined` respectivamente. *

**Ejemplo #1**
```js
console.log(undefined && "perro"); //undefined
console.log(null && "perro"); //null
console.log(false && "perro"); //false
console.log(true && "perro"); //perro
```

**Ejemplo #2**
```js
const frutas = ["Manzana","Pera","Limon","Banana"];
const longitud = frutas.length; //4

console.log(longitud === 4 && "Tengo 4 frutas");
//salida: Tengo 4 frutas
```
Ya que mi arreglo tiene 4 posiciones, la condicion `longitud === 4` evalúa como `true`, por ello se ve por consola "Tengo 4 frutas". 

### **Operador `||`**
Este operador solo se ejecuta si la condición a evaluar es `false`, `null` o `undefined`.

#### **Sintaxis**
```js
expr1 || expr2
```
> *Sí `expr1` evalua como `false`,`null` o `undefined` entonces se ejecuta `expr2`*
> *Sí `expr1` evalua como `true` entonces la salida es un `true` también*

**Ejemplo #1**

```js
console.log(undefined || "perro"); //perro
console.log(null || "perro"); //perro
console.log(true || "perro"); //true
console.log(false || "perro"); //perro
```
**Ejemplo #2**
```js
const frutas = ["Manzana","Pera","Limon","Banana"];
const longitud = frutas.length; //4

console.log(longitud === 3 || "Tengo frutas");
//salida: Tengo frutas
```
Ya que la condición es `false` entonces se ve por consola el mensaje "Tengo frutas". 

**Consideraciones acerca de los operadores de cortocircuito:**
* Son un poco más abstractos pero sencillos de comprender.
* Son usados bastante en React.js para el **renderizado condicional de componentes**.
* No se deben confundir con el `or` e `and` lógicos, que si bien se escriben igual, pero cumplen funciones diferentes.
* Cuando usamos `&&` y la condición a evaluar es falsa, se imprimira `false`.
* Cuando usamos `||` y la condición a evaluar es verdadera, se imprimira `true`.
* En estos 2 últimos aspectos es mejor recibir o devolver un booleano (`true` o `false`) que un `null` o un `undefined`.

## **6. Nullish coalescing operator**<a name="id6"></a> 
Este operador algo extraño para muchos (`??`) es muy similar al operador de cortocircuito `||` que exclusivamente sirve para evaluar condiciones `null` o `undefined`.

#### **Sintaxis**
```js
expr1 ?? expr2
```
> *Sí `expr1` es `null` o `undefined` se ejecuta la `expr2`.*
> *Sí `expr1` no es `null` ni `undefined` se ejecuta la misma `expr1`.*

**Ejemplo #1**
```js
console.log(undefined ?? "perro"); //perro
console.log(null ?? "perro"); //perro
console.log("gato" ?? "perro"); //gato
console.log(false ?? "perro"); //false
console.log(true ?? "perro"); //true
console.log([] ?? "perro"); //[]
console.log({} ?? "perro"); //{}
//Solo devolverá "perro" si la expreción a evaluar es `null` o `undefined`.
```
**Consideraciones con el nullish coalescing operator**
* Al evaluar `null` y `undefined` este operador no es muy usado, pero no está demás saber de su existencia. 

## **7. Optional Chaining**<a name="id7"></a>

El operador de **Encadenamiento Opcional** permite realizar una especie de "validación" en nuestros programas cuando empleamos objetos, arreglos o funciones. 

Considere el siguiente ejemplo, donde se tiene un array `edades` con algunos números, lo que se desea obtener es un nuevo arreglo que contenga las edades que son mayores a 18 años, (con un `filter` bastante sencillo de hacer).

```js
const edades = [8,19,20,10,70,56];
const mayoresDeEdad = edades.filter((edad) => {
  return edad >= 18
});
console.info(mayoresDeEdad); // [19,20,70,56]
```

Ahora bien, imaginemos que el arreglo de edades lo obtenemos realizando una consulta a una API o a una base de datos, por ende cabe la posibilidad de que en el transcurso de dicha consulta pase algún imprevisto o un error que produzca que nuestro array `edades` venga con un valor de `null` o `undefined` , como se ve a continuación: 

![img](https://raw.githubusercontent.com/crisdux/img-dev-to/master/undefined.gif)

Al intentar recorrer un arreglo que es `undefined` JavaScript lanza este error interrumpiendo la ejecución del programa por completo, este comportamiento en librerías frontend modernas como por ejemplo React se lo paga caro, ya que el sitio entero puede dejar de funcionar. Entonces, ¿qué podemos hacer para poder controlar un poco mejor este escenario? La solución buena, y quizá la más sencilla es emplear el **Optional Chaining** o **Eencadenamiento Opcional**.

**Sintaxis**

```js
obj.val?.prop
obj.val?.[expr]
obj.arr?.[index]
obj.func?.(args)
```

Como se puede observar en la sintaxis para usar el **Optional Chaining** basta anteponer `?` al arreglo, objeto o función, nuestro ejemplo quedaría de la siguiente manera:

```js
const edades = [8,19,20,10,70,56];
const mayoresDeEdad = edades?.filter((edad) => {
  return edad >= 18
});
console.info(mayoresDeEdad); // [19,20,70,56]
```

Coloquialmente y omitiendo por un momento el uso de lenguaje técnico, al emplear el `?` es como si dijeramos: "Okay JavaScript, quiero que me recorras el arreglo `edades` que te estoy pasando, pero si por cualquier motivo `edades` viene como `null` o como `undefined` no me lances por consola esos errores feos que tienes y que matan mi app web, mejor solo mostrame por salida ese `undefined` del arreglo. Gracias JavaScript 😍". El resultado sería el siguiente: 

![img2](https://raw.githubusercontent.com/crisdux/img-dev-to/master/undefined2.gif)

Quizá hasta este punto te preguntes: ¿Por qué se llama encadenamiento opcional? La respuesta radica en su mismo nombre y para ilustrarlo mejor veremos un último ejemplo: 

Consideremos que tenemos el siguiente objeto `auto` y deseamos imprimir por consola la `serie` 

```js
const auto ={
  marca: "Toyota",
  ruedas: 4,
  motor:{
    tamaño:"Grande",
    serie: "ARFY-9562"
  }
}
console.log(auto.motor.serie); //"ARFY-9562"
```

> *En este ejemplo para ejemplificar el concepto de encadenamiento opcional no se usa destructuración de objetos* 

Una vez más imaginemos que por cualquier motivo intentamos acceder al `motor` y luego a su `serie` pero estos no vienen en el objeto `auto` 

```js
const auto ={
  marca: "Toyota",
  ruedas: 4
}
console.log(auto.motor.serie);
//Uncaught TypeError: can't access property "serie", auto.motor is undefined 
```

Nuevamente nuestro pequeño programa exploto, pero ya sabemos como solucionar esto, ¿verdad? 😁

```js
const auto ={
  marca: "Toyota",
  ruedas: 4,
}
console.log(auto?.motor?.serie); // undefined
```

Bastaría con hacer `motor?` pero para entender mejor por qué esta característica de JavaScript se llama encadenamiento opcional hacemos `auto?.motor?.serie` así nos aseguramos que el objeto principal `auto` tampoco venga como `null` o `undefined`. 

Si bien es horrible ver un `undefined` por consola al desarrollar software considero que es mucho mejor que un error de tipo: <span style="color:#e53935"> *Uncaught TypeError: can't access property "serie", auto.motor is undefined* </span> que muchas veces provocan que nuestro programa falle en su totalidad. 

## **8. Obtener valores únicos con Set**<a name="id8"></a>

La [MDN](https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Set) menciona que el objeto `Set`  permite almacenar valores únicos de cualquier tipo, incluso [valores primitivos](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) u referencias a objetos.

Por ende, es bastante usado cuando necesitamos eliminar elementos duplicados de un arreglo, por ejemplo:

```js
const numeros = [1,5,49,8,2,20,80,1,49,20];
const numerosSinRepetidos =[...new Set(numeros)];
console.info(numerosSinRepetidos); //[1, 5, 49, 8, 2, 20, 80]
```

## **9. `includes` para una condición múltiple**<a name="id9"></a>

El método `includes` puede emplearse para escribir una condicional de una manera muy elegante y sencilla de comprender: 

```js

let x= "b";
if(x==="a" || x==="b" || x==="c" || ) { // pasa la condición si x=a, o x=b o x=c
  console.log("x es: a, b o c");
}
//salida: "x es: a, b o c"

//Manera resumida:
if(["a","b","c"].includes(x)){
  console.log("x es: a, b o c | Use includes");
}
//salida:"x es: a, b o c | Use includes"

```

Consideraciones a tomar en cuenta:

* Evalúa una condición usando un  "o lógico"  (`||`).
* Evalúa una sola variable.
* `includes` retorna siempre un valor booleano.

Si deseas conocer mejor el funcionamiento del método [includes](https://dev.to/crisfer4217/las-bondades-del-metodo-includes-en-javascript-o1i) puedes leer este post mío. 

## **10. Potencias**<a name="id10"></a>

En vez de hacer esto:

```js
Math.pow(2,3); // 8
```

Puedes hacer esto: 

```js
2**3 // 8
```

## **11. Obtener el último elemento de un arreglo**<a name="id11"></a>

Podemos usar el método `slice` para devolver el último elemento del arreglo.

```js
const numeros = [1,2,3,4,5];
console.log(numeros.slice(-1)); // [5]
```

¡Bastante sencillo!

¡Espero que hayas disfrutado y sobre todo comprendido estos 10 tips con JavaScript, hasta un nuevo post! **Happy Coding**

## **Conclusiones**<a name="id11"></a>

* Puedes convertir un string a number anteponiendo en operador `+` a la variable a convertir.
* Puedes convertir un number a string concatenándolo con un string vacío.
* El operador ternario, if abreviado o if de una sola línea permite redactar código más legible.
* Utiliza los operadores de corto circuito `&&` y `||` para evaluar condiciones.
* El nullish coalescing operator permite evaluar condiciones `null` y `undefined`.
* Emplea el optional chaining para verificar si arreglos, objetos o funciones son `null` o `undefined`.
* El objeto `Set` combinado con el spread operator es útil para limpiar arreglos de duplicados.
* El método `includes` permite escribir condiciones más limpias para evaluar.
* Puedes usar el operador de doble asterisco para elevar un número a otro.
* Podemos usar el método `slice` con parámetros negativos para devolver el último elemento de un arreglo.

---

## **Referencias**<a name="id12"></a>

* https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Operators/Conditional_Operator
* https://5uoaggxrhmuk3atsxrir2opine--developer-mozilla-org.translate.goog/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
* https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Set

---

![gif](https://media.giphy.com/media/DAtJCG1t3im1G/giphy.gif)