Saltar al contenido principal

13 publicaciones etiquetados con "io19"

Ver Todas las Etiquetas

`Intl.NumberFormat`

· 4 min de lectura
Mathias Bynens ([@mathias](https://twitter.com/mathias)) y Shane F. Carr

Es posible que ya estés familiarizado con la API Intl.NumberFormat, ya que ha sido compatible con varios entornos modernos durante algún tiempo.

En su forma más básica, Intl.NumberFormat te permite crear una instancia de formato reutilizable que admite el formato de números adaptado al idioma. Al igual que otras APIs de Intl.*Format, una instancia de formateador admite ambos métodos: format y formatToParts:

`globalThis`

· 2 min de lectura
Mathias Bynens ([@mathias](https://twitter.com/mathias))

Si has escrito JavaScript para usar en un navegador web antes, es posible que hayas usado window para acceder al this global. En Node.js, quizás hayas usado global. Si has escrito código que debe funcionar en cualquiera de estos entornos, quizás detectaste cuál de estos está disponible y luego lo usaste, pero la lista de identificadores a verificar crece con el número de entornos y casos de uso que deseas admitir. Esto se sale de control rápidamente:

Referencias débiles y finalizadores

· 11 min de lectura
Sathya Gunasekaran ([@_gsathya](https://twitter.com/_gsathya)), Mathias Bynens ([@mathias](https://twitter.com/mathias)), Shu-yu Guo ([@_shu](https://twitter.com/_shu)), y Leszek Swirski ([@leszekswirski](https://twitter.com/leszekswirski))

Generalmente, las referencias a los objetos se mantienen fuertemente en JavaScript, lo que significa que mientras tengas una referencia al objeto, no será recolectado por el recolector de basura.

const ref = { x: 42, y: 51 };
// Mientras tengas acceso a `ref` (o cualquier otra referencia al
// mismo objeto), el objeto no será recolectado por el recolector de basura.

Actualmente, WeakMaps y WeakSets son la única forma de referenciar de manera virtualmente débil un objeto en JavaScript: agregar un objeto como una clave a un WeakMap o WeakSet no impide que sea recolectado por el recolector de basura.

const wm = new WeakMap();
{
const ref = {};
const metaData = 'foo';
wm.set(ref, metaData);
wm.get(ref);
// → metaData
}
// Ya no tenemos una referencia a `ref` en este alcance de bloque, así que
// puede ser recolectado por el recolector de basura ahora, incluso aunque sea una clave en `wm` a
// la cual todavía tenemos acceso.

Array.prototype.sort` estable

· 4 min de lectura
Mathias Bynens ([@mathias](https://twitter.com/mathias))

Supongamos que tienes un array de perros, donde cada perro tiene un nombre y una calificación. (Si esto suena a un ejemplo extraño, debes saber que hay una cuenta de Twitter que se especializa exactamente en esto… ¡No preguntes!)

// Nota cómo el array está preordenado alfabéticamente por `name`.
const doggos = [
{ name: 'Abby', rating: 12 },
{ name: 'Bandit', rating: 13 },
{ name: 'Choco', rating: 14 },
{ name: 'Daisy', rating: 12 },
{ name: 'Elmo', rating: 12 },
{ name: 'Falco', rating: 13 },
{ name: 'Ghost', rating: 14 },
];
// Ordena los perros por `rating` en orden descendente.
// (Esto actualiza `doggos` directamente).
doggos.sort((a, b) => b.rating - a.rating);

`Object.fromEntries`

· 4 min de lectura
Mathias Bynens ([@mathias](https://twitter.com/mathias)), susurrador de JavaScript

Object.fromEntries es una adición útil a la biblioteca incorporada de JavaScript. Antes de explicar lo que hace, es útil entender la API Object.entries ya existente.

Object.entries

La API Object.entries ha existido durante un tiempo.

Para cada par clave-valor en un objeto, Object.entries te da un array donde el primer elemento es la clave y el segundo elemento es el valor.

Object.entries es especialmente útil en combinación con for-of, ya que permite iterar elegantemente sobre todos los pares clave-valor en un objeto:

const object = { x: 42, y: 50 };
const entries = Object.entries(object);
// → [['x', 42], ['y', 50]]

for (const [key, value] of entries) {
console.log(`El valor de ${key} es ${value}.`);
}
// Registros:
// El valor de x es 42.
// El valor de y es 50.

Desafortunadamente, no hay una forma fácil de volver del resultado de entries a un objeto equivalente... ¡hasta ahora!

Object.fromEntries

La nueva API Object.fromEntries realiza la inversa de Object.entries. Esto hace que sea fácil reconstruir un objeto basado en sus entradas:

const object = { x: 42, y: 50 };
const entries = Object.entries(object);
// → [['x', 42], ['y', 50]]

const result = Object.fromEntries(entries);
// → { x: 42, y: 50 }

Un caso de uso común es transformar objetos. Ahora puedes hacerlo iterando sobre sus entradas y luego usando métodos de arrays con los que ya puedas estar familiarizado:

const object = { x: 42, y: 50, abc: 9001 };
const result = Object.fromEntries(
Object.entries(object)
.filter(([ key, value ]) => key.length === 1)
.map(([ key, value ]) => [ key, value * 2 ])
);
// → { x: 84, y: 100 }

En este ejemplo, usamos filter para obtener solo las claves de longitud 1, es decir, solo las claves x y y, pero no la clave abc. Luego usamos map sobre las entradas restantes y devolvemos un par clave-valor actualizado por cada una. En este ejemplo, duplicamos cada valor multiplicándolo por 2. El resultado final es un nuevo objeto con solo las propiedades x y y, y los nuevos valores.

Combinadores de Promesas

· 5 min de lectura
Mathias Bynens ([@mathias](https://twitter.com/mathias))

Desde la introducción de las promesas en ES2015, JavaScript ha soportado exactamente dos combinadores de promesas: los métodos estáticos Promise.all y Promise.race.

Actualmente, dos nuevas propuestas están atravesando el proceso de estandarización: Promise.allSettled, y Promise.any. Con estas adiciones, habrá un total de cuatro combinadores de promesas en JavaScript, cada uno permitiendo diferentes casos de uso.

`Array.prototype.flat` y `Array.prototype.flatMap`

· 2 min de lectura
Mathias Bynens ([@mathias](https://twitter.com/mathias))

Array.prototype.flat

El arreglo en este ejemplo tiene varios niveles de profundidad: contiene un arreglo que a su vez contiene otro arreglo.

const array = [1, [2, [3]]];
// ^^^^^^^^^^^^^ arreglo exterior
// ^^^^^^^^ arreglo interior
// ^^^ arreglo más interior

Array#flat devuelve una versión aplanda de un arreglo dado.

array.flat();
// → [1, 2, [3]]

// …es equivalente a:
array.flat(1);
// → [1, 2, [3]]

La profundidad predeterminada es 1, pero puedes pasar cualquier número para aplanar recursivamente hasta esa profundidad. Para seguir aplanando recursivamente hasta que el resultado no contenga más arreglos anidados, pasamos Infinity.

// Aplanar recursivamente hasta que el arreglo no contenga más arreglos anidados:
array.flat(Infinity);
// → [1, 2, 3]

¿Por qué este método se llama Array.prototype.flat y no Array.prototype.flatten? ¡Lee nuestro artículo #SmooshGate para descubrirlo!

Array.prototype.flatMap

Aquí hay otro ejemplo. Tenemos una función duplicate que toma un valor y devuelve un arreglo que contiene ese valor dos veces. Si aplicamos duplicate a cada valor en un arreglo, terminamos con un arreglo anidado.

const duplicate = (x) => [x, x];

[2, 3, 4].map(duplicate);
// → [[2, 2], [3, 3], [4, 4]]

Entonces puedes llamar a flat sobre el resultado para aplanar el arreglo:

[2, 3, 4].map(duplicate).flat(); // 🐌
// → [2, 2, 3, 3, 4, 4]

Dado que este patrón es tan común en la programación funcional, ahora hay un método dedicado llamado flatMap para ello.

[2, 3, 4].flatMap(duplicate); // 🚀
// → [2, 2, 3, 3, 4, 4]

flatMap es un poco más eficiente en comparación con realizar un map seguido de un flat por separado.

¿Interesado en casos de uso de flatMap? Consulta la explicación de Axel Rauschmayer.

Compatibilidad con Array#{flat,flatMap}

Separadores numéricos

· 2 min de lectura
Mathias Bynens ([@mathias](https://twitter.com/mathias))

Los literales numéricos grandes son difíciles de interpretar rápidamente para el ojo humano, especialmente cuando hay muchos dígitos repetidos:

1000000000000
1019436871.42

Para mejorar la legibilidad, una nueva característica del lenguaje JavaScript permite guiones bajos como separadores en literales numéricos. Por lo tanto, lo anterior ahora puede reescribirse para agrupar los dígitos por miles, por ejemplo:

`String.prototype.matchAll`

· 3 min de lectura
Mathias Bynens ([@mathias](https://twitter.com/mathias))

Es común aplicar repetidamente la misma expresión regular en una cadena para obtener todas las coincidencias. Hasta cierto punto, esto ya es posible hoy en día utilizando el método String#match.

En este ejemplo, encontramos todas las palabras que consisten únicamente en dígitos hexadecimales y luego registramos cada coincidencia:

const string = 'Números hex mágicos: DEADBEEF CAFE';
const regex = /\b\p{ASCII_Hex_Digit}+\b/gu;
for (const match of string.match(regex)) {
console.log(match);
}

// Salida:
//
// 'DEADBEEF'
// 'CAFE'

Sin embargo, esto solo te da las subcadenas que coinciden. Normalmente, no solo quieres las subcadenas, también deseas información adicional como el índice de cada subcadena o los grupos de captura dentro de cada coincidencia.

Ya es posible lograr esto escribiendo tu propio bucle y haciendo un seguimiento de los objetos de coincidencia tú mismo, pero es un poco tedioso y no muy conveniente:

const string = 'Números hex mágicos: DEADBEEF CAFE';
const regex = /\b\p{ASCII_Hex_Digit}+\b/gu;
let match;
while (match = regex.exec(string)) {
console.log(match);
}

// Salida:
//
// [ 'DEADBEEF', índice: 19, entrada: 'Números hex mágicos: DEADBEEF CAFE' ]
// [ 'CAFE', índice: 28, entrada: 'Números hex mágicos: DEADBEEF CAFE' ]

La nueva API String#matchAll lo hace más fácil que nunca: ahora puedes escribir un simple bucle for-of para obtener todos los objetos de coincidencia.

const string = 'Números hex mágicos: DEADBEEF CAFE';
const regex = /\b\p{ASCII_Hex_Digit}+\b/gu;
for (const match of string.matchAll(regex)) {
console.log(match);
}

// Salida:
//
// [ 'DEADBEEF', índice: 19, entrada: 'Números hex mágicos: DEADBEEF CAFE' ]
// [ 'CAFE', índice: 28, entrada: 'Números hex mágicos: DEADBEEF CAFE' ]

String#matchAll es especialmente útil para expresiones regulares con grupos de captura. Te proporciona toda la información de cada coincidencia individual, incluidos los grupos de captura.

const string = 'Repositorios favoritos de GitHub: tc39/ecma262 v8/v8.dev';
const regex = /\b(?<owner>[a-z0-9]+)\/(?<repo>[a-z0-9\.]+)\b/g;
for (const match of string.matchAll(regex)) {
console.log(`${match[0]} en ${match.index} con '${match.input}'`);
console.log(`→ owner: ${match.groups.owner}`);
console.log(`→ repo: ${match.groups.repo}`);
}

`Intl.ListFormat`

· 4 min de lectura
Mathias Bynens ([@mathias](https://twitter.com/mathias)) y Frank Yung-Fong Tang

Las aplicaciones web modernas suelen usar listas que consisten en datos dinámicos. Por ejemplo, una aplicación de visualización de fotos podría mostrar algo como:

Esta foto incluye Ada, Edith, y Grace.

Un juego basado en texto podría tener un tipo diferente de lista:

Elige tu superpoder: invisibilidad, psicokinesis, o empatía.

Como cada idioma tiene diferentes convenciones y palabras para el formato de listas, implementar un formateador de listas localizado no es trivial. Esto no solo requiere una lista de todas las palabras (como “y” u “o” en los ejemplos anteriores) para cada idioma que se quiera soportar, sino que también es necesario codificar las convenciones de formato exactas para todos esos idiomas. El CLDR de Unicode proporciona estos datos, pero para usarlos en JavaScript, deben estar integrados y enviados junto con el código de otras bibliotecas. Esto desafortunadamente aumenta el tamaño del paquete de dichas bibliotecas, lo que impacta negativamente los tiempos de carga, los costos de parseo/compilación y el consumo de memoria.