Pular para o conteúdo principal

13 postagens marcadas com "io19"

Ver todas os Marcadores

`Intl.NumberFormat`

· Leitura de 4 minutos
Mathias Bynens ([@mathias](https://twitter.com/mathias)) e Shane F. Carr

Você pode já estar familiarizado com a API Intl.NumberFormat, já que tem sido suportada em ambientes modernos há algum tempo.

Na sua forma mais básica, Intl.NumberFormat permite criar uma instância de formatador reutilizável que suporta formatação de números sensível ao local. Assim como outras APIs Intl.*Format, uma instância de formatador suporta tanto o método format quanto o método formatToParts:

`globalThis`

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

Se você já escreveu JavaScript para uso em um navegador web antes, pode ter usado window para acessar o this global. No Node.js, você pode ter usado global. Se você escreveu um código que deve funcionar em qualquer um dos ambientes, pode ter detectado qual deles está disponível e usado isso - mas a lista de identificadores a verificar cresce com o número de ambientes e casos de uso que você deseja suportar. Isso foge do controle rapidamente:

Referências fracas e finalizadores

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

Geralmente, referências a objetos são fortemente mantidas no JavaScript, o que significa que enquanto você tiver uma referência ao objeto, ele não será coletado pelo garbage collector.

const ref = { x: 42, y: 51 };
// Enquanto você tiver acesso a `ref` (ou qualquer outra referência ao
// mesmo objeto), o objeto não será coletado pelo garbage collector.

Atualmente, WeakMaps e WeakSets são a única maneira de referenciar um objeto de forma quase fraca no JavaScript: adicionar um objeto como chave a um WeakMap ou WeakSet não impede que ele seja coletado pelo garbage collector.

const wm = new WeakMap();
{
const ref = {};
const metaData = 'foo';
wm.set(ref, metaData);
wm.get(ref);
// → metaData
}
// Não temos mais uma referência a `ref` neste escopo de bloco, então ele
// pode ser coletado pelo garbage collector agora, mesmo que seja uma chave no `wm`
// ao qual ainda temos acesso.

Ordenação estável de `Array.prototype.sort`

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

Digamos que você tenha um array de cachorros, onde cada cachorro tem um nome e uma classificação. (Se isso parecer um exemplo estranho, você deve saber que existe uma conta no Twitter que se especializa exatamente nisso... Não pergunte!)

// Note como o array já está ordenado alfabeticamente por `nome`.
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 },
];
// Ordene os cachorros por `rating` em ordem decrescente.
// (Isso atualiza `doggos` diretamente.)
doggos.sort((a, b) => b.rating - a.rating);

`Object.fromEntries`

· Leitura de 4 minutos
Mathias Bynens ([@mathias](https://twitter.com/mathias)), encantador de JavaScript

Object.fromEntries é uma adição útil à biblioteca JavaScript incorporada. Antes de explicar o que ele faz, é útil entender a API pré-existente Object.entries.

Object.entries

A API Object.entries existe há algum tempo.

Para cada par de chave-valor em um objeto, Object.entries fornece um array em que o primeiro elemento é a chave e o segundo elemento é o valor.

Object.entries é especialmente útil em combinação com for-of, pois permite iterar de forma muito elegante sobre todos os pares de chave-valor em um objeto:

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

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

Infelizmente, não há uma maneira fácil de voltar do resultado de entries para um objeto equivalente… até agora!

Object.fromEntries

A nova API Object.fromEntries realiza a operação inversa de Object.entries. Isso facilita a reconstrução de um objeto com base em seus entries:

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

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

Um caso de uso comum é a transformação de objetos. Agora você pode fazer isso iterando sobre seus entries e usando métodos de array com os quais você já pode 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 }

Neste exemplo, estamos filterando o objeto para obter apenas chaves de comprimento 1, ou seja, apenas as chaves x e y, mas não a chave abc. Em seguida, mapeamos os entries restantes e retornamos um par atualizado de chave-valor para cada um. Neste exemplo, dobramos cada valor multiplicando-o por 2. O resultado final é um novo objeto, com apenas as propriedades x e y, e os novos valores.

Combinadores de Promise

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

Desde a introdução de promises no ES2015, o JavaScript suporta exatamente dois combinadores de promise: os métodos estáticos Promise.all e Promise.race.

Duas novas propostas estão atualmente passando pelo processo de padronização: Promise.allSettled e Promise.any. Com essas adições, haverá um total de quatro combinadores de promise no JavaScript, cada um possibilitando diferentes casos de uso.

`Array.prototype.flat` e `Array.prototype.flatMap`

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

Array.prototype.flat

O array neste exemplo tem vários níveis de profundidade: contém um array que, por sua vez, contém outro array.

const array = [1, [2, [3]]];
// ^^^^^^^^^^^^^ array externo
// ^^^^^^^^ array interno
// ^^^ array mais interno

Array#flat retorna uma versão achatada de um array fornecido.

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

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

A profundidade padrão é 1, mas você pode passar qualquer número para achatar recursivamente até essa profundidade. Para continuar achatando recursivamente até o resultado não conter mais arrays aninhados, passamos Infinity.

// Achatar recursivamente até o array não conter mais arrays aninhados:
array.flat(Infinity);
// → [1, 2, 3]

Por que esse método é chamado de Array.prototype.flat e não Array.prototype.flatten? Leia nosso artigo sobre #SmooshGate para descobrir!

Array.prototype.flatMap

Aqui está outro exemplo. Temos uma função duplicate que recebe um valor e retorna um array que contém esse valor duas vezes. Se aplicarmos duplicate a cada valor de um array, terminamos com um array aninhado.

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

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

Você pode então chamar flat no resultado para achatar o array:

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

Como esse padrão é tão comum na programação funcional, agora há um método dedicado flatMap para ele.

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

flatMap é um pouco mais eficiente em comparação a fazer um map seguido de um flat separadamente.

Interessado em casos de uso para flatMap? Confira a explicação de Axel Rauschmayer.

Suporte a Array#{flat,flatMap}

Separadores Numéricos

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

Literais numéricos grandes são difíceis para o olho humano interpretar rapidamente, especialmente quando há muitos dígitos repetidos:

1000000000000
1019436871.42

Para melhorar a legibilidade, uma nova funcionalidade da linguagem JavaScript permite sublinhados como separadores em literais numéricos. Assim, o exemplo acima agora pode ser reescrito para agrupar os dígitos por milhar, por exemplo:

`String.prototype.matchAll`

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

É comum aplicar repetidamente a mesma expressão regular em uma string para obter todas as correspondências. Até certo ponto, isso já é possível hoje usando o método String#match.

Neste exemplo, encontramos todas as palavras que consistem apenas em dígitos hexadecimais e, em seguida, registramos cada correspondência:

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);
}

// Saída:
//
// 'DEADBEEF'
// 'CAFE'

No entanto, isso só fornece os substrings que correspondem. Normalmente, você não quer apenas os substrings, mas também informações adicionais, como o índice de cada substring ou os grupos de captura dentro de cada correspondência.

Já é possível alcançar isso escrevendo seu próprio loop e rastreando os objetos de correspondência você mesmo, mas é um pouco chato e não muito prático:

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);
}

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

A nova API String#matchAll torna isso mais fácil do que nunca: agora você pode escrever um simples loop for-of para obter todos os objetos de correspondência.

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);
}

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

String#matchAll é especialmente útil para expressões regulares com grupos de captura. Ele fornece todas as informações para cada correspondência individual, incluindo os grupos de captura.

const string = 'Repositórios favoritos do 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]} em ${match.index} com '${match.input}'`);
console.log(`→ proprietário: ${match.groups.owner}`);
console.log(`→ repositório: ${match.groups.repo}`);
}

`Intl.ListFormat`

· Leitura de 4 minutos
Mathias Bynens ([@mathias](https://twitter.com/mathias)) e Frank Yung-Fong Tang

Aplicações web modernas frequentemente usam listas compostas de dados dinâmicos. Por exemplo, um aplicativo visualizador de fotos pode exibir algo como:

Esta foto inclui Ada, Edith, e Grace.

Um jogo baseado em texto pode ter um tipo diferente de lista:

Escolha seu superpoder: invisibilidade, psicocinese, ou empatia.

Como cada idioma tem convenções de formatação de listas e palavras diferentes, implementar um formatador de listas localizado não é trivial. Isso não só exige uma lista de todas as palavras (como “e” ou “ou” nos exemplos acima) para cada idioma que você deseja suportar — além disso, você precisa codificar as convenções de formatação exatas para todos esses idiomas! O Unicode CLDR fornece esses dados, mas para usá-los em JavaScript, eles precisam ser integrados e enviados junto com o restante do código da biblioteca. Isso, infelizmente, aumenta o tamanho do pacote para essas bibliotecas, o que impacta negativamente os tempos de carregamento, o custo de análise/compilação e o consumo de memória.