Aller au contenu principal

`await` de niveau supérieur

· 6 minutes de lecture
Myles Borins ([@MylesBorins](https://twitter.com/MylesBorins))

await de niveau supérieur permet aux développeurs d'utiliser le mot-clé await en dehors des fonctions asynchrones. Il agit comme une grande fonction asynchrone, obligeant d'autres modules qui les import à attendre avant de commencer à évaluer leur corps.

Coalescence nulle

· 7 minutes de lecture
Justin Ridgewell

La proposition de coalescence nulle (??) ajoute un nouvel opérateur de court-circuit destiné à gérer les valeurs par défaut.

Vous connaissez peut-être déjà les autres opérateurs de court-circuit && et ||. Ces deux opérateurs traitent les valeurs « vraies » (truthy) et « fausses » (falsy). Imaginez l'exemple de code lhs && rhs. Si lhs (lire, côté gauche) est falsy, l'expression est évaluée à lhs. Sinon, elle est évaluée à rhs (lire, côté droit). L'inverse est vrai pour l'exemple de code lhs || rhs. Si lhs est truthy, l'expression est évaluée à lhs. Sinon, elle est évaluée à rhs.

L'enchaînement optionnel

· 5 minutes de lecture
Maya Armyanova ([@Zmayski](https://twitter.com/Zmayski)), briseuse d'enchaînements optionnels

Les longues chaînes d'accès aux propriétés en JavaScript peuvent être sujettes à des erreurs, car chacune d'entre elles peut s'évaluer à null ou undefined (aussi connues sous le nom de valeurs nulles). Vérifier l'existence des propriétés à chaque étape peut facilement se transformer en une structure profondément imbriquée avec des déclarations if ou une condition if longue répliquant la chaîne d'accès aux propriétés :

Incorporer JSON, autrement dit JSON ⊂ ECMAScript

· 7 minutes de lecture
Mathias Bynens ([@mathias](https://twitter.com/mathias))

Avec la proposition JSON ⊂ ECMAScript, JSON devient un sous-ensemble syntaxique d'ECMAScript. Si vous êtes surpris que cela n'était pas déjà le cas, vous n'êtes pas le seul !

Le comportement ancien d'ES2018

En ES2018, les littéraux de chaîne de caractères d'ECMAScript ne pouvaient pas contenir les caractères séparateurs de ligne U+2028 LINE SEPARATOR et U+2029 PARAGRAPH SEPARATOR non échappés, car ils sont considérés comme des terminaux de ligne même dans ce contexte :

// Une chaîne contenant un caractère U+2028 brut.
const LS = '
';
// → ES2018 : SyntaxError

// Une chaîne contenant un caractère U+2029 brut, produit par `eval` :
const PS = eval('"\u2029"');
// → ES2018 : SyntaxError

Cela posait problème car les chaînes JSON peuvent contenir ces caractères. En conséquence, les développeurs devaient implémenter une logique de post-traitement spécialisée lors de l'intégration de JSON valide dans des programmes ECMAScript pour gérer ces caractères. Sans cette logique, le code pouvait comporter des bugs subtils, voire des problèmes de sécurité !

`Intl.NumberFormat`

· 5 minutes de lecture
Mathias Bynens ([@mathias](https://twitter.com/mathias)) et Shane F. Carr

Vous connaissez peut-être déjà l’API Intl.NumberFormat, car elle est prise en charge dans les environnements modernes depuis un certain temps.

Dans sa forme la plus basique, Intl.NumberFormat vous permet de créer une instance de formateur réutilisable qui prend en charge le formatage des nombres adapté à la langue locale. Tout comme les autres API Intl.*Format, une instance de formateur prend en charge les méthodes format et formatToParts :

`globalThis`

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

Si vous avez déjà écrit du JavaScript pour une utilisation dans un navigateur web, vous avez peut-être utilisé window pour accéder au this global. Dans Node.js, vous avez peut-être utilisé global. Si vous avez écrit du code qui doit fonctionner dans les deux environnements, vous avez peut-être détecté lequel de ces éléments est disponible, puis utilisé celui-ci — mais la liste des identifiants à vérifier s'allonge avec le nombre d'environnements et de cas d'utilisation que vous souhaitez prendre en charge. Cela devient vite ingérable :

Références faibles et finalisateurs

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

Généralement, les références aux objets sont fortement conservées en JavaScript, ce qui signifie que tant que vous avez une référence à l'objet, il ne sera pas collecté par le garbage collector.

const ref = { x: 42, y: 51 };
// Tant que vous avez accès à `ref` (ou toute autre référence
// au même objet), l'objet ne sera pas collecté par le garbage collector.

Actuellement, les WeakMap et WeakSet sont les seuls moyens de référencer un objet de manière quasi-faible en JavaScript : ajouter un objet en tant que clé à un WeakMap ou WeakSet ne l'empêche pas d'être collecté par le garbage collector.

const wm = new WeakMap();
{
const ref = {};
const metaData = 'foo';
wm.set(ref, metaData);
wm.get(ref);
// → metaData
}
// Nous n'avons plus de référence à `ref` dans ce bloc de portée, donc
// il peut être collecté par le garbage collector, même s'il est une clé
// dans `wm` auquel nous avons encore accès.

Trie stable `Array.prototype.sort`

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

Disons que vous avez un tableau de chiens, où chaque chien a un nom et une note. (Si cet exemple vous semble bizarre, sachez qu'il existe un compte Twitter qui se spécialise exactement là-dedans… Ne demandez pas !)

// Notez comment le tableau est pré-trié par ordre alphabétique par `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 },
];
// Triez les chiens par `rating` en ordre décroissant.
// (Cela met à jour `doggos` en place.)
doggos.sort((a, b) => b.rating - a.rating);

`Symbol.prototype.description`

· Une minute de lecture
Mathias Bynens ([@mathias](https://twitter.com/mathias))

Les Symbol en JavaScript peuvent recevoir une description lors de leur création :

const symbol = Symbol('foo');
// ^^^^^

Auparavant, la seule façon d'accéder à cette description par programme était de manière indirecte via Symbol.prototype.toString() :

const symbol = Symbol('foo');
// ^^^^^
symbol.toString();
// → 'Symbol(foo)'
// ^^^
symbol.toString().slice(7, -1); // 🤔
// → 'foo'

Cependant, ce code semble légèrement magique, pas très explicite, et viole le principe « exprimer l'intention, non l'implémentation ». Cette technique ne permet pas non plus de faire la distinction entre un symbole sans description (c'est-à-dire Symbol()) et un symbole dont la description est une chaîne vide (c'est-à-dire Symbol('')).

`Object.fromEntries`

· 4 minutes de lecture
Mathias Bynens ([@mathias](https://twitter.com/mathias)), spécialiste en JavaScript

Object.fromEntries est un ajout utile à la bibliothèque JavaScript intégrée. Avant d'expliquer ce qu'il fait, il est utile de comprendre l'API existante Object.entries.

Object.entries

L'API Object.entries existe depuis un certain temps.

Pour chaque paire clé-valeur dans un objet, Object.entries vous donne un tableau où le premier élément est la clé et le second élément est la valeur.

Object.entries est particulièrement utile en combinaison avec for-of, car il vous permet d'itérer très élégamment sur toutes les paires clé-valeur d'un objet :

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

for (const [key, value] of entries) {
console.log(`La valeur de ${key} est ${value}.`);
}
// Affiche :
// La valeur de x est 42.
// La valeur de y est 50.

Malheureusement, il n'y a pas de moyen facile de revenir du résultat des entries à un objet équivalent… jusqu'à maintenant !

Object.fromEntries

La nouvelle API Object.fromEntries effectue l'inverse de Object.entries. Cela facilite la reconstruction d'un objet à partir de ses 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 }

Un cas d'utilisation courant est la transformation d'objets. Vous pouvez maintenant faire cela en itérant sur ses entries, puis en utilisant des méthodes de tableau que vous connaissez probablement déjà :

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 }

Dans cet exemple, nous appliquons un filter sur l'objet pour ne récupérer que les clés de longueur 1, c'est-à-dire seulement les clés x et y, mais pas la clé abc. Nous effectuons ensuite un map sur les entries restantes et retournons une paire clé-valeur mise à jour pour chacune. Dans cet exemple, nous doublons chaque valeur en la multipliant par 2. Le résultat final est un nouvel objet, avec uniquement les propriétés x et y, et les nouvelles valeurs.