隆Estamos en directo en Twitch!

隆Entra y participa!

Imagen de la etiqueta javascript

ES2022 / ES13: novedades de la 煤ltima versi贸n de JavaScript

5 minutos de lectura驴Una errata? Edita el art铆culo

JavaScript no deja de evolucionar y todos los a帽os se a帽aden nuevas funcionalidades para mejorar la productividad de los desarrolladores. Este a帽o 2021 no iba a ser una excepci贸n y te explico las nuevas caracter铆sticas que ya tienes disponible en la mayor铆a de navegadores.

1. Logical Assignment Operators (&&= ||= ??=)

Los operadores l贸gicos &&, || y ?? ahora tambi茅n pueden usarse para asignar valores de una forma m谩s sencilla y corta. Perfecto para asignar valores por defecto a variables.

// Si x es falsy, se le asigna y
x ||= y
// Equivale a...
x || (x = y)

// Si x es truthy, se le asigna y
x &&= y
// Equivale a...
x && (x = y)

// Si x es null o undefined, se le asigna y
x ??= y
// Equivale a...
x ?? (x = y)

Hay que tener en cuenta que en estas asignaciones, adem谩s, entra el juego la evaluaci贸n short-circuit. Esto quiere decir que estas asignaciones l贸gicas se evaluan de izquierda a derecha. Si una expresi贸n l贸gica no se cumple, no se eval煤a la siguiente.

Esto es importante para no cometer errores:

// este nuevo tipo de asignaci贸n con &&
x &&= y
// 鉁 es equivalente a...
x && (x = y)
// 鉂 NO es equivalente a...
x = x && y
// ya que la asignaci贸n ocurre siempre independientemente de la evaluaci贸n

2. Numeric Separator

Leer algunas cifras en JavaScript puede ser una tarea dif铆cil. Para solucionar esto, el nuevo separador num茅rico _ te permite identificar de manera m谩s sencilla cualquier n煤mero.

// Es dif铆cil saber qu茅 cifra representa
1000000000
19436871.42

// 隆Con Numeric Separator es m谩s f谩cil!
1_000_000_000 // Ah, es mil millones
100_000_000 // Y esto es cien millones
19_436_871.42 // 隆De un vistazo!

3. Promise.any

驴Alguna vez has querido esperar una lista de promesas y que, al resolverse correctamente una cualquiera, continuar con la ejecuci贸n de tu c贸digo? Pues para eso se incorpora Promise.any().

const promises = [
  fetch('/from-external-api'),
  fetch('/from-memory'),
  fetch('/from-new-api'),
]

try {
  // espera a la primera respuesta correcta que termine
  const first = await Promise.any(promises)
  // La m谩s r谩pida fue la de memoria
  console.log(first) // respuesta desde 'from-memory'
} catch (error) {
  // 隆Todas las promesas han fallado!
  console.assert(error instanceof AggregateError)
  // Log the rejection values:
  console.log(error.errors)
  // 鈫 [
  //     <TypeError: Failed to fetch /from-external-api>,
  //     <TypeError: Failed to fetch /from-memory>,
  //     <TypeError: Failed to fetch /from-new-api>
  //   ]
}

AggregateError

Como has podido ver en el ejemplo anterior, ahora cuando la promesa falla, se devuelve una instancia de AggregateError. Este error es una instancia de Error y tiene una propiedad llamada errors que contiene una lista de errores para cada promesa que fall贸.

La diferencia con Promise.race

Promise.race y Promise.any son muy similares. La diferencia es que Promise.race se resuelve cuando cualquier promesa ha sido resuelta o rechazada. En cambio Promise.any ignora las promesas que son rechazadas y s贸lo se resuelve cuando se resuelve la primera… o se rechaza cuando todas las promesas se han rechazado.

La tabla de diferencias de Promise

Para que lo veas m谩s claro, he preparado una peque帽a tabla para diferenciar los diferentes m茅todos de Promise a la hora de trabajar con un array de promesas, para que eligas la que m谩s encaje con tu caso de uso.

+鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝+鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝-鈭+鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭-鈭+
| M茅todo             | Descripci贸n                                      | A帽adida en...   |
+鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝+鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝-鈭+鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝-+
| Promise.allSettled | Espera a todas las promesas se resuelvan o no    | ES2020          |
| Promise.all        | Se para cuando una promesa es rechazada          | ES2015          |
| Promise.race       | Se para cuando una promesa es rechaza o resuelta | ES2015          |
| Promise.any        | Se para cuando una promesa es resuelta           | ES2021          |
+鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝+鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝-鈭掆垝鈭+鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭掆垝鈭-鈭+

4. replaceAll

Hasta ahora, reemplazar todas las instancias de una cadena de texto en una cadena de texto te obligaba a usar Regex ya que replace, si le pasabas un string, lo que hac铆a era s贸lo reemplazar la primera instancia encontrada.

// 隆Quiero cambiar las manzanas por bananas!
'馃崗馃崗馃崑馃崑馃崐馃崐'.replace('馃崗', '馃崒')
// Pero qu茅...
// -> '馃崒馃崗馃崑馃崑馃崐馃崐'

// 隆Tienes que usar Regex para conseguirlo!
'馃崗馃崗馃崑馃崑馃崐馃崐'.replace(/馃崗/g, '馃崒')

// 隆Hasta ahora! 隆Hola replaceAll!
'馃崗馃崗馃崑馃崑馃崐馃崐'.replaceAll('馃崗', '馃崒')

replaceAll queda mucho m谩s legible en nuestro c贸digo y hace justo lo que esperaba: cambiar todas las instancias de una cadena de texto en una cadena de texto.

5. WeakRef

WeakRef te permite crear una referencia d茅bil a un objeto para no prevenir que se destruya por el Garbage Collector de JavaScript. 驴Por qu茅? Pues por qu茅 cuando creamos un objeto, especialmente si son grandes, estos no son autom谩ticamente destruidos por el Garbage Collector si existe una referencia a ellos.

Con el m茅todo deref de WeakRef, podemos acceder a la referencia del objeto. Si la referencia al objeto ha sido eliminada, se devuelve undefined.

// Al crear un objeto...
let coords = { x: 13, y: 72 }
// Mientras tengas acceso a 茅l directamente,
// el objeto no ser谩 liberado de memoria
// por el Garbage Collector

// Ahora podemos crear una referencia d茅bil al objeto
const weakCoords = new WeakRef(coords)

// Recuperamos las propiedades del elemento
const ref = weakCoords.deref()
if (ref) {
  console.log('Todav铆a tenemos acceso a las coordenadas')
  ref.x // -> 13
} else {
  // ref es `undefined`
  console.log('La referencia ha sido eliminada')
}

Una cosa que debes tener en cuenta con WeakRef es que… seguramente es mejor si no lo usas. Esta funcionalidad est谩 pensado para casos muy espec铆ficos que, en general, acabar谩n en librer铆as y frameworks. Est谩 bien que conozcas su existencia pero los casos de uso son muy limitados. La recolecci贸n de basura en JavaScript puede variar mucho dependiendo del navegador, entorno y especificaciones del sistema.

Contenido del art铆culo

Comparte el art铆culo