Mis à jour ces 90 derniers jours 24 nouvelles · 29 révisées
API pour annuler des opérations asynchrones (fetch, event listeners, streams). Créé un signal qui peut être passe a n'importe quelle API supportant l'annulation.
Un bouton d'arrêt d'urgence : tu peux stopper une opération en cours a tout moment.
const controller = new AbortController();
fetch('/api/data', { signal: controller.signal })
.catch(err => {
if (err.name === 'AbortError') console.log('Annule');
});
// Annuler apres 5s
setTimeout(() => controller.abort(), 5000);Cas d'usage : Timeout de requêtes fetch, annulation lors du démontage d'un composant React, cleanup de listeners.
Méthodes fonctionnelles : map (transformer), filter (filtrer), reduce (accumuler), find/findIndex (chercher), some/every (tester), flat/flatMap (aplatir). Chainables et non-mutantes.
Un pipeline de cuisine : laver (filter), couper (map), mixer (reduce) — chaque étape transforme sans toucher au stock original.
const result = users
.filter(u => u.active)
.map(u => u.name)
.sort();
const total = prices.reduce((sum, p) => sum + p, 0);
const found = items.find(i => i.id === 42);Cas d'usage : Transformation de données, filtrage de listes, calculs d'aggregation, recherche.
Méthode statique (Stage 4, listée par TC39 pour ES2026) qui construit un tableau à partir d'un itérable asynchrone, d'un itérable synchrone de promesses ou d'un objet array-like, et renvoie une promesse du tableau. Chaque valeur est attendue séquentiellement, à la différence de Promise.all qui lance tout en parallèle. Largement disponible dans les navigateurs depuis janvier 2024.
Ramasser les lettres d'une boîte au fil de leur arrivée, dans l'ordre, jusqu'à la dernière.
async function* pages() {
for (let p = 1; p <= 3; p++) yield await fetchPage(p);
}
const tout = await Array.fromAsync(pages()); // [page1, page2, page3]
// Avec fonction de transformation (attendue elle aussi)
const tailles = await Array.fromAsync([1, 2, 3], async n => n * 2);
// Séquentiel : 5 promesses de 100 ms ≈ 500 ms (Promise.all ≈ 100 ms)Cas d'usage : Collecter un flux paginé, un ReadableStream ou un curseur base de données en tableau.
Zone de mémoire brute de taille fixe, non redimensionnable. Accessible via des TypedArrays (Uint8Array, Float32Array, etc.) ou DataView pour lire/écrire des données binaires.
Un terrain vague clôture : il existe en mémoire, mais tu as besoin d'outils (TypedArray) pour y construire quelque chose.
const buf = new ArrayBuffer(16);
const view = new Uint8Array(buf);
view[0] = 255;
const float = new Float32Array(buf);
// Meme memoire, vue differenteCas d'usage : Traitement d'images, audio, fichiers binaires, communication avec WebGL ou WASM.
Syntaxe compacte pour les fonctions anonymes avec =>, qui ne possède ni son propre this, ni arguments, ni super. Le this est hérité du scope lexical englobant.
Un assistant qui n'a pas de bureau propre (pas de this) : il utilise toujours le bureau de son chef (scope parent).
const add = (a, b) => a + b;
const greet = name => `Hello ${name}`;
const getObj = () => ({ key: 'value' });
class Timer {
start() {
setInterval(() => console.log(this), 1000);
// this = instance Timer (lexical)
}
}Cas d'usage : Callbacks, méthodes de tableaux (map, filter), quand on veut capturer le this du parent.
Sucre syntaxique sur les Promises. async déclaré une fonction retournant une Promise, await suspend l'exécution jusqu'a la résolution. Rend le code asynchrone lisible comme du synchrone.
Commander un café et attendre au comptoir : tu ne fais rien d'autre en attendant (await), mais le reste du café (event loop) continue de tourner.
async function fetchUser(id) {
try {
const res = await fetch(`/api/users/${id}`);
return await res.json();
} catch (err) {
console.error('Fetch failed', err);
}
}Cas d'usage : Écrire du code asynchrone lisible pour les appels API, accès BD, opérations fichiers.
Fonction async function* combinant générateurs et async/await. Peut yield des valeurs de manière asynchrone, consommable via for await...of.
Un chef qui prépare les plats un par un (yield) en attendant chaque ingrédient de la livraison (await).
async function* pollData(url, ms) {
while (true) {
const res = await fetch(url);
yield await res.json();
await new Promise(r => setTimeout(r, ms));
}
}Cas d'usage : Polling périodique, lecture de flux réseau, traitement de files de messages.
Protocole pour iterer sur des séquences asynchrones. L'objet implémenté [Symbol.asyncIterator]() et next() retourne une Promise de {value, done}. Utilisable avec for await...of.
Un podcast en streaming : chaque épisode arrive de manière asynchrone, et tu les écoutes un par un.
async function* fetchPages(url) {
let page = 1;
while (true) {
const data = await fetch(`${url}?p=${page++}`);
const json = await data.json();
if (!json.length) return;
yield json;
}
}
for await (const page of fetchPages('/api')) {}Cas d'usage : Pagination API, lecture de streams, traitement de données en flux.
Objet global fournissant des opérations atomiques sur les SharedArrayBuffer : load, store, add, sub, and, or, xor, wait, notify. Garantit l'intégrité en contexte multithread.
Un tour de parole officiel : chaque personne attend son tour pour parler (wait/notify) et ses mots sont enregistres sans interruption (opérations atomiques).
const sab = new SharedArrayBuffer(4);
const arr = new Int32Array(sab);
Atomics.store(arr, 0, 42);
Atomics.load(arr, 0); // 42
Atomics.add(arr, 0, 8); // ancien: 42
Atomics.load(arr, 0); // 50Cas d'usage : Synchronisation entre workers, compteurs partages, mutex software.
Fichier index.ts/js qui re-exporte les modules d'un dossier pour simplifier les imports. Peut nuire au tree shaking et au temps de build si mal utilise.
Un sommaire de livre : pratique pour trouver un chapitre, mais si le sommaire force a charger tout le livre, c'est contre-productif.
// components/index.ts (barrel)
export { Button } from './Button';
export { Modal } from './Modal';
export { Input } from './Input';
// Usage
import { Button } from './components';Cas d'usage : API publiques de librairies, organisation de dossiers de composants.
Type primitif pour représenter des entiers de taille arbitraire, au-delà de Number.MAX_SAFE_INTEGER (2^53 - 1). Créé avec le suffixe n ou BigInt().
Un cahier avec un nombre illimité de pages pour écrire des nombres, contrairement a une calculatrice a écran fixe.
const big = 9007199254740993n;
big + 1n; // 9007199254740994n
// Attention : pas de melange
// big + 1; // TypeError
BigInt(Number.MAX_SAFE_INTEGER) + 1n;Cas d'usage : Identifiants de bases de données 64-bit, calculs financiers de précision, cryptographie.
Méthodes de Function.prototype pour contrôler this. call(ctx, ...args) et apply(ctx, [args]) appellent immédiatement. bind(ctx, ...args) retourne une nouvelle fonction avec this lie.
call = téléphoner a quelqu'un maintenant. apply = idem mais tu lis la liste des courses. bind = enregistrer le numéro en favori pour appeler plus tard.
function greet(msg) { return `${msg}, ${this.name}`; }
const user = { name: 'Bob' };
greet.call(user, 'Hi'); // 'Hi, Bob'
greet.apply(user, ['Hi']); // 'Hi, Bob'
const bound = greet.bind(user);
bound('Hey'); // 'Hey, Bob'Cas d'usage : Fixer le this dans les callbacks, emprunter des méthodes d'un autre objet, partial application.
Formateur et linter unique en Rust pour JavaScript, TypeScript, JSX, JSON, CSS, GraphQL et HTML, successeur de Rome. Biome 2.4 (10 février 2026) a ajouté les extraits embarqués et l'accessibilité HTML ; Biome 2.5 (5 juin 2026) dépasse 500 règles, apporte des corrections automatiques dans les plugins GritQL et le lint inter-fichiers. Il propose un lint conscient des types sans dépendre de tsc.
Un seul artisan qui pose le carrelage et fait les joints, au lieu de deux corps de métier à coordonner.
# Installer, initialiser, vérifier
pnpm add -D @biomejs/biome
npx biome init # crée biome.json
npx biome check --write . # formate + corrige le lint
# biome.json (extrait)
# { "formatter": { "indentStyle": "space" },
# "linter": { "rules": { "recommended": true } } }Cas d'usage : Remplacer Prettier + ESLint par un seul outil et une seule config, surtout sur des projets neufs.
API de communication entre contextes de même origine (onglets, iframes, workers). Plus simple que SharedWorker pour du broadcast de messages.
Une radio interne d'entreprise : tous les bureaux (onglets) branchées sur la même fréquence reçoivent le message.
// Onglet 1
const bc = new BroadcastChannel('auth');
bc.postMessage({ type: 'logout' });
// Onglet 2
const bc2 = new BroadcastChannel('auth');
bc2.onmessage = (e) => {
if (e.data.type === 'logout') redirectToLogin();
};Cas d'usage : Synchroniser le logout entre onglets, mettre a jour le theme, notifier les onglets d'un changement.
Runtime JavaScript/TypeScript tout-en-un (exécution, gestionnaire de paquets, bundler, runner de tests) bâti sur JavaScriptCore. Bun 1.4 (20 août 2026) est la première version issue de la réécriture complète de Zig vers Rust ; elle annonce +1 517 tests de la suite Node.js qui passent, 100 % sur node:events et node:sqlite, un démarrage deux fois plus rapide et des API intégrées comme Bun.Image, Bun.markdown, Bun.cron ou Bun.WebView.
Un couteau suisse : moins spécialisé que chaque outil séparé, mais un seul objet dans la poche.
// serveur.ts — lancé par : bun serveur.ts (TypeScript natif)
Bun.serve({
port: 3000,
routes: {
'/static/*': { dir: './public' }, // fichiers statiques intégrés
},
fetch(req) {
return new Response(Bun.markdown.html('# Bonjour **Bun**'));
},
});
// bun install, bun test --parallel, bun build --compileCas d'usage : Scripts, API légères, monorepos où le temps d'installation compte ; CI (bun install annoncé 15 fois plus rapide que npm sur un projet Next.js).
Pile LIFO (Last In, First Out) qui trace les contextes d'exécution des fonctions en cours. Chaque appel de fonction empile un frame, chaque return le depile.
Une pile d'assiettes : tu poses la dernière en haut et tu reprends toujours celle du dessus.
function a() { b(); }
function b() { c(); }
function c() { console.trace(); }
a();
// c -> b -> a -> globalCas d'usage : Lire les stack traces d'erreurs et comprendre les dépassements de pile (stack overflow).
File d'attente (macrotask queue) ou sont places les callbacks de setTimeout, setInterval, I/O et evenements DOM. Traites après que la call stack et la microtask queue sont vides.
La file d'attente normale a la poste : tu passes après les clients prioritaires (microtasks).
setTimeout(() => console.log('macro'), 0);
Promise.resolve().then(() => console.log('micro'));
// micro, macroCas d'usage : Planifier des taches non-urgentes qui ne doivent pas bloquer le rendu ou les promesses en cours.
Situation ou le module A importe B et B importe A. En CommonJS, on obtient un export partiel. En ESM, ca fonctionne grâce aux live bindings mais peut causer des bugs subtils.
Deux personnes qui se tiennent la porte mutuellement : ca fonctionne si l'une passe en premier, mais ca peut devenir un blocage.
// a.js
import { b } from './b.js';
export const a = 'A' + b;
// b.js
import { a } from './a.js';
export const b = 'B'; // a est undefined ici en CJS!Cas d'usage : Détecter et casser les cycles avec des outils comme madge ou eslint-plugin-import.
Fonction qui capture et retient les variables de son scope parent même après que celui-ci a termine son exécution. C'est le mécanisme fondamental derrière les callbacks, modules et data privacy en JS.
Un sac a dos que tu emportes en quittant la maison : même loin de chez toi, tu as toujours accès a ce que tu y as mis.
function counter() {
let count = 0;
return {
increment: () => ++count,
get: () => count
};
}
const c = counter();
c.increment(); // 1Cas d'usage : Encapsuler un état prive dans un module ou créer des fonctions factory avec configuration injectée.
CommonJS (require/module.exports) est synchrone et historique dans Node.js ; ESM (import/export) est le standard du langage, statique et propice au tree shaking. Les deux mondes communiquent désormais : require() d'un module ESM synchrone est activé par défaut depuis Node 22.12.0 et 20.19.0, et déclaré stable en Node 25.4.0. Un module avec top-level await reste inaccessible à require() (ERR_REQUIRE_ASYNC_MODULE).
CommonJS = commander par téléphone (dynamique, a la demande). ESM = liste de courses pre-écrite (statique, analysable a l'avance).
// lib.mjs (ESM)
export const lire = (p) => p;
// app.cjs (CommonJS) — Node ≥ 22.12 / 20.19
const { lire } = require('./lib.mjs'); // OK si pas de top-level await
if (process.features.require_module) {
console.log('require(esm) disponible');
}Cas d'usage : ESM pour tout nouveau code ; publier en ESM seul devient viable puisque les consommateurs CommonJS peuvent faire require(esm). TypeScript 5.8 modélise ce comportement avec --module nodenext.
Compose enchaîné des fonctions de droite a gauche, pipe de gauche a droite. Chaque fonction reçoit le résultat de la précédenté. Fondamental en programmation fonctionnelle.
Une chaîne de montage : chaque poste (fonction) transforme le produit et le passe au suivant.
const pipe = (...fns) => (x) =>
fns.reduce((acc, fn) => fn(acc), x);
const transform = pipe(
str => str.trim(),
str => str.toLowerCase(),
str => str.replace(/\s+/g, '-')
);
transform(' Hello World '); // 'hello-world'Cas d'usage : Transformation de données en pipeline, middleware, traitement de texte, ETL.
Transformer une fonction a N arguments en N fonctions a 1 argument chainables. Chaque appel retourne une nouvelle fonction jusqu'a ce que tous les arguments soient fournis.
Un formulaire en plusieurs étapes : chaque page collecte une info, et le formulaire n'est soumis qu'a la dernière étape.
const curry = (fn) => {
const arity = fn.length;
return function go(...args) {
return args.length >= arity
? fn(...args)
: (...more) => go(...args, ...more);
};
};
const add = curry((a, b, c) => a + b + c);
add(1)(2)(3); // 6Cas d'usage : Configuration progressive de fonctions, création de variantes spécialisées, composition fonctionnelle.
Retarde l'exécution d'une fonction jusqu'a ce qu'un délai se soit écoulé sans nouvel appel. Chaque appel réinitialisé le timer. N'exécuté que le dernier appel.
L'ascenseur qui attend que plus personne n'entre pendant 3 secondes avant de fermer les portes.
function debounce(fn, ms) {
let timer;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), ms);
};
}
const search = debounce(query => fetch(query), 300);Cas d'usage : Recherche en temps réel (attendre que l'utilisateur arrête de taper), resize handler, auto-save.
Runtime JavaScript/TypeScript sécurisé par défaut, avec TypeScript natif, formateur, linter et runner de tests intégrés. Deno 2.0 (9 octobre 2024) a apporté la compatibilité Node/npm (package.json, node_modules, spécificateurs npm:), le registre JSR et les workspaces. Deno 2.8 (22 mai 2026) implémente import defer ; Deno 2.9 (25 juin 2026) lit directement les lockfiles npm/pnpm/yarn/Bun, ajoute deno desktop et annonce un démarrage à froid deux fois plus rapide (17,3 ms).
Un navigateur pour le serveur : rien n'est autorisé tant que l'utilisateur n'a pas dit oui.
// main.ts — lancé par : deno run --allow-net=api.exemple.fr main.ts
import chalk from 'npm:chalk@5'; // paquet npm direct
import { assert } from 'jsr:@std/assert'; // registre JSR
const res = await fetch('https://api.exemple.fr/ping');
assert(res.ok);
console.log(chalk.green('ok'));
// Lire un fichier sans --allow-read → PermissionDeniedCas d'usage : Scripts d'administration, edge functions, projets qui veulent des permissions explicites et zéro configuration TypeScript.
Syntaxe ES6 pour extraire des valeurs d'objets ou tableaux dans des variables distinctes. Supporte les valeurs par défaut, le renommage et l'imbrication.
Ouvrir un colis et ranger chaque article directement dans le bon tiroir au lieu de tout laisser dans le carton.
const { name, age = 25 } = user;
const [first, ...rest] = [1, 2, 3];
// Nested
const { address: { city } } = user;
// Rename
const { name: userName } = user;Cas d'usage : Extraire proprement les props d'un composant React, les champs d'une réponse API, les arguments de fonction.
import() est une expression qui renvoie une promesse du module : chargement conditionnel et découpage du code à l'exécution. Le second argument accepte des attributs d'import (ES2025) : import('./data.json', { with: { type: 'json' } }). Pour différer seulement l'évaluation (et non le chargement), la proposition « import defer » (Stage 3) est supportée par TypeScript 5.9 et Deno 2.8.
Commander un plat a la carte au lieu du menu complet : tu ne charges que ce dont tu as besoin, quand tu en as besoin.
const chargerGraphe = async () => {
const { Chart } = await import('./chart.js');
return new Chart(data);
};
// Attribut d'import (ES2025) : JSON en module
const { default: conf } = await import('./conf.json', {
with: { type: 'json' }
});
if (user.isAdmin) {
const { AdminPanel } = await import('./admin.js');
}Cas d'usage : Code splitting dans les SPA, chargement lazy de routes/composants lourds, chargement conditionnel.
JS a des types d'erreurs built-in : TypeError (mauvais type), ReferenceError (variable inconnue), SyntaxError, RangeError, URIError. On peut créer des erreurs custom via extends Error.
Différents codes d'alerte dans un hôpital : chaque type indique immédiatement la nature du problème.
class AppError extends Error {
constructor(message, code) {
super(message);
this.name = 'AppError';
this.code = code;
}
}
throw new AppError('Not found', 404);Cas d'usage : Créer des erreurs métier typées pour un meilleur handling et des messages clairs.
Méthode statique (Stage 4, listée par TC39 pour ES2026) qui indique si une valeur est un vrai objet Error, y compris DOMException, via une marque interne posée par le constructeur, comme Array.isArray. Elle fonctionne entre realms (iframe, vm, worker) là où instanceof Error échoue, et rejette un objet qui n'a fait qu'emprunter Error.prototype. Livrée dans V8 13.6 (Node.js 24) ; support navigateur encore incomplet selon MDN.
Vérifier le tampon officiel d'un document plutôt que le papier à en-tête, qui s'imite.
try {
throw 'chaîne brute';
} catch (e) {
if (!Error.isError(e)) e = new Error(String(e)); // normaliser
console.error(e.message);
}
Error.isError(new TypeError()); // true
Error.isError({ __proto__: Error.prototype }); // false
// Erreur venue d'une iframe : instanceof Error → false, isError → trueCas d'usage : Bibliothèques de journalisation, frontières iframe/worker/vm, normalisation des valeurs rejetées.
Pratique de publier un paquet npm uniquement en modules ES, sans build CommonJS parallèle. Elle est devenue défendable depuis que require(esm) est activé par défaut dans Node 22.12.0 et 20.19.0 (stable en 25.4.0) : un consommateur CommonJS peut charger le paquet. L'article « Move on to ESM-only » (5 février 2025) chiffre l'adoption d'ESM sur npm à 25,8 % fin 2024 et liste les coûts du double format : deux jeux de fichiers et de .d.ts, singletons dupliqués, taille doublée.
Arrêter d'imprimer un journal en deux formats quand tous les kiosques acceptent le nouveau.
{
"name": "ma-lib",
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
}
},
"engines": { "node": ">=20.19" }
}Cas d'usage : Nouvelles bibliothèques, outils en ligne de commande, paquets destinés au navigateur (tree shaking) ou aux versions de Node qui supportent require(esm).
Deux phases de propagation des evenements DOM. Capturing descend du document vers la cible, bubbling remonte de la cible vers le document. Par défaut, les listeners écoûtent en phase bubbling.
Capturing = le facteur descend l'escalier pour trouver la bonne porte. Bubbling = la nouvelle remonte de voisin en voisin jusqu'au concierge.
// Bubbling (defaut)
el.addEventListener('click', handler);
// Capturing
el.addEventListener('click', handler, true);
// Ou avec options
el.addEventListener('click', handler, {
capture: true
});Cas d'usage : Intercepter des evenements avant qu'ils n'atteignent leur cible (capture), ou déléguer après (bubbling).
Attacher un seul event listener sur un parent au lieu d'un sur chaque enfant. Exploite le bubbling pour capturer les evenements des descendants via event.target.
Un standardiste unique qui reçoit tous les appels de l'immeuble et les redirigé vers le bon bureau.
document.getElementById('list')
.addEventListener('click', (e) => {
if (e.target.matches('li.item')) {
handleClick(e.target.dataset.id);
}
});Cas d'usage : Listes dynamiques, tableaux avec beaucoup de lignes, éléments ajoutes après le chargement.
Pattern publish/subscribe ou un émetteur envoie des evenements nommes et des listeners s'y abonnent. Base de EventTarget (DOM) et EventEmitter (Node.js).
Une radio : l'émetteur diffuse sur une fréquence (evenement) et tous les récepteurs branches sur cette fréquence captent le message.
class Emitter {
#events = {};
on(evt, fn) {
(this.#events[evt] ??= []).push(fn);
}
emit(evt, ...args) {
this.#events[evt]?.forEach(fn => fn(...args));
}
}
const bus = new Emitter();
bus.on('data', console.log);Cas d'usage : Communication découplé entre composants, bus d'evenements, architecture event-driven.
Mécanisme central qui gère l'exécution asynchrone en JS. Il surveille la call stack et, quand elle est vide, depile les callbacks des queues (microtask d'abord, puis macrotask).
Un serveur de restaurant qui sert les plats quand le client a fini de manger : il attend que la table soit libre avant d'apporter le suivant.
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
console.log('4');
// 1, 4, 3, 2Cas d'usage : Comprendre l'ordre d'exécution du code asynchrone et debugger les problèmes de timing.
Environnement abstrait dans lequel le code JS est évalué. Contient le Variable Environment, le Lexical Environment et la valeur de this. Créé pour chaque appel de fonction et le scope global.
La fiche d'identité d'un appel de fonction : qui elle est (this), ce qu'elle connaît (variables), et d'ou elle vient (scope).
// Global EC cree au demarrage
const x = 1;
function foo() {
// Nouveau EC pour foo()
const y = 2;
console.log(x + y); // accede au parent EC
}
foo();Cas d'usage : Comprendre en profondeur le comportement de this, le hoisting et la scope chain.
Le mot-clé using déclare une variable dont la méthode [Symbol.dispose]() est appelée automatiquement à la sortie du bloc ; await using fait de même avec [Symbol.asyncDispose](). La proposition « Explicit Resource Management » est terminée (Stage 4) et figure dans la liste TC39 des propositions attendues pour l'édition ES2027. Elle est déjà livrée dans V8 13.6, donc dans Node.js 24 (6 mai 2025), et TypeScript la compile depuis la 5.2. Équivalent du try-with-resources de Java ou du using de C#.
Un robinet auto-coupant : il se ferme tout seul quand tu quittes la pièce, pas besoin de penser a le fermer.
class Conn {
[Symbol.dispose]() { console.log('connexion fermée'); }
}
function requete() {
using db = new Conn(); // libéré à la sortie du bloc
using pile = new DisposableStack();
pile.defer(() => console.log('nettoyage différé'));
return 'ok';
} // ordre inverse : pile puis db
// async : await using s = await ouvrirSocket();Cas d'usage : Connexions base de données, descripteurs de fichiers, verrous, transactions : tout ce qui exige un nettoyage garanti même en cas d'exception. DisposableStack regroupe plusieurs ressources à libérer dans l'ordre inverse.
API moderne de requêtes HTTP basée sur les Promises, remplaçant XMLHttpRequest. Retourne une Response avec des méthodes pour parser le body (json, text, blob, etc.).
Un service de livraison moderne : tu passes commande (fetch), tu reçois un bon de livraison (Response), puis tu ouvres le colis (.json()).
const res = await fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'Alice' })
});
if (!res.ok) throw new Error(res.status);
const data = await res.json();Cas d'usage : Toute communication HTTP : appels API REST, upload de fichiers, téléchargement de ressources.
API qui permet d'enregistrer un callback de nettoyage appelé quand un objet observe est garbage-collecte. Companion de WeakRef pour le cleanup de ressources.
Un notaire qui exécute le testament (cleanup) quand la personne (objet) n'est plus la.
const registry = new FinalizationRegistry((heldValue) => {
console.log(`Cleaned up: ${heldValue}`);
});
let obj = { heavy: new ArrayBuffer(1e6) };
registry.register(obj, 'heavy-buffer');
obj = null; // callback sera appele au GCCas d'usage : Libération de ressources externes (handles fichier, connexions) quand l'objet JS associe est GC.
for...of itere sur les valeurs des iterables (Array, Map, Set, String). for...in itere sur les clés enumerables d'un objet, y compris la prototype chain.
for...of = lire chaque page d'un livre. for...in = lire la table des matières (et potentiellement celles des annexes héritées).
const arr = ['a', 'b', 'c'];
for (const val of arr) console.log(val); // a, b, c
for (const idx in arr) console.log(idx); // 0, 1, 2
const obj = { x: 1, y: 2 };
for (const key in obj) console.log(key); // x, yCas d'usage : for...of pour les tableaux et iterables, for...in pour les propriétés d'objets (avec hasOwnProperty).
Processus automatique de libération de la mémoire non référencée. V8 utilise un GC generationnel : minor GC (young génération) fréquent et major GC (old génération) moins souvent.
Un service de nettoyage qui ramasse les objets abandonnes dans un parc : si personne ne les réclame, ils sont jetés.
let obj = { data: new Array(1000000) };
// obj est referencee, pas GC
obj = null;
// Plus de reference -> eligible au GC
// WeakRef pour reference faible
const weak = new WeakRef(someObj);Cas d'usage : Comprendre les fuites mémoire, optimiser l'allocation, choisir entre Map/WeakMap.
Fonction spéciale (function*) qui peut se suspendre via yield et reprendre. Retourne un itérateur. Permet la génération paresseuse de séquences potentiellement infinies.
Un livre dont tu tournes les pages une par une (yield) : l'histoire ne se déroule que quand tu le demandes.
function* fibonacci() {
let [a, b] = [0, 1];
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
const fib = fibonacci();
fib.next().value; // 0, 1, 1, 2...Cas d'usage : Séquences paresseuses, pagination, flux de données, implémentation de iterables custom.
Mécanisme par lequel les déclarations de variables (var) et fonctions sont remontées en haut de leur scope durant la phase de compilation. Les let/const sont hoistees mais restent dans la Temporal Dead Zone.
Comme un prof qui note tous les noms au tableau avant le début du cours, mais ne remplit les notes qu'au fur et a mesure.
console.log(a); // undefined (var hoiste)
var a = 5;
sayHi(); // OK, declaration hoistee
function sayHi() { console.log('Hi'); }
console.log(b); // ReferenceError (TDZ)
let b = 10;Cas d'usage : Comprendre pourquoi une variable vaut undefined au lieu de lancer une erreur, debugger l'ordre d'exécution.
Immediately Invoked Function Expression : fonction anonyme exécutée immédiatement a sa déclaration. Créé un scope isole pour éviter la pollution globale. Moins utile depuis les modules ESM.
Un feu d'artifice a usage unique : tu l'allumes et il s'exécute immédiatement, sans laisser de trace.
const result = (() => {
const secret = 42;
return secret * 2;
})();
// secret n'existe pas ici
console.log(result); // 84Cas d'usage : Isolation de scope dans du code legacy, initialisation immédiate, éviter les collisions globales.
Principe de ne jamais modifier les données existantes mais de créer de nouvelles copies avec les changements. Object.freeze() pour une immutabilite superficielle en JS natif.
Un livre publie : pour corriger une erreur, tu publies une nouvelle édition au lieu de rayer l'ancienne.
// Immutable update
const user = { name: 'Alice', age: 30 };
const updated = { ...user, age: 31 };
// Array
const arr = [1, 2, 3];
const added = [...arr, 4];
// Freeze
const frozen = Object.freeze({ x: 1 });Cas d'usage : State management (Redux, React state), historique undo/redo, détection de changements performante.
Syntaxe ES2025 qui accole des métadonnées à un import : import data from './x.json' with { type: 'json' }. L'attribut type: 'json' est le seul défini par ECMAScript (« JSON modules », ES2025) ; les navigateurs ajoutent type: 'css'. L'ancienne forme assert est abandonnée. Node.js exige l'attribut pour importer un JSON et l'a déclaré stable en 22.12.0 et 20.18.3 ; TypeScript 6.0 déprécie assert.
L'étiquette « fragile » sur un colis : elle dit au transporteur comment traiter le contenu, pas ce qu'il est.
// Statique
import conf from './config.json' with { type: 'json' };
console.log(conf.port);
// Dynamique
const { default: i18n } = await import('./fr.json', {
with: { type: 'json' }
});
// Navigateur : feuille de style comme module
// import feuille from './app.css' with { type: 'css' };Cas d'usage : Configuration, traductions, fixtures : importer du JSON sans fs.readFile ni bundler.
Proposition TC39 au Stage 3 (« Deferring Module Évaluation ») : import defer * as ns from './lourd.js' charge et lie le module tout de suite mais n'exécute son code qu'au premier accès à une propriété de ns. Un module avec top-level await est évalué immédiatement. TypeScript 5.9 (1er août 2025) accepte la syntaxe et Deno 2.8 (22 mai 2026) l'exécute ; le support navigateur est encore limité.
Une pièce dont on a la clé sur soi mais dont on n'allume la lumière qu'en entrant.
import defer * as pdf from './generateur-pdf.js'; // lié, pas évalué
console.log('démarrage rapide');
export function exporter(doc) {
// Première lecture d'une propriété : le module s'exécute ici
return pdf.render(doc);
}
// Attention : les effets de bord du module sont déplacés aussiCas d'usage : Réduire le temps de démarrage d'une CLI ou d'un serveur qui charge de gros modules rarement utilisés, sans rendre le code appelant asynchrone.
API navigateur via <script type='importmap'> qui mappe des specifiers de modules a des URLs. Permet d'utiliser des bare imports sans bundler.
Un annuaire qui traduit les noms (lodash) en adresses réelles (https://cdn.../lodash.js).
<script type="importmap">
{ "imports": { "lodash": "/libs/lodash.js" } }
</script>
<script type="module">
import _ from 'lodash';
</script>Cas d'usage : Prototypage rapide sans bundler, migration progressive vers ESM natif dans le navigateur.
Optimisation V8 qui cache l'emplacement mémoire d'une propriété après le premier accès. Monomorphique (1 type) = rapide, polymorphique (2-4) = OK, megamorphique (5+) = lent.
Se souvenir exactement ou tu as range tes clés (toujours la même poche) au lieu de fouiller partout a chaque fois.
// Monomorphique (rapide)
function getX(obj) { return obj.x; }
getX({ x: 1 }); getX({ x: 2 }); // meme forme
// Megamorphique (lent)
getX({ x: 1 });
getX({ x: 1, y: 2 });
getX({ x: 1, z: 3 });
getX({ a: 0, x: 1 }); // formes differentesCas d'usage : Garder des formes d'objets cohérentes dans les hot paths pour maximiser les performances V8.
API qui observe de manière asynchrone la visibilité d'un élément par rapport a un ancêtre ou au viewport. Remplace les calculs manuels de getBoundingClientRect dans un scroll listener.
Un vigile qui te prévient automatiquement quand quelqu'un entre dans la zone de surveillance, sans que tu doives regarder constamment.
const observer = new IntersectionObserver(
(entries) => entries.forEach(e => {
if (e.isIntersecting) loadImage(e.target);
}),
{ threshold: 0.1 }
);
document.querySelectorAll('img[data-src]')
.forEach(img => observer.observe(img));Cas d'usage : Lazy loading d'images, infinité scroll, animations au scroll, tracking d'impressions.
Méthodes paresseuses sur les itérateurs natifs, standardisées dans ES2025 : map, filter, take, drop, flatMap, reduce, forEach, some, every, find et toArray, plus Iterator.from pour envelopper un itérable quelconque. Chaque étape consomme les valeurs à la demande, sans tableau intermédiaire, ce qui permet de traiter des séquences infinies. ES2026 ajoute Iterator.concat.
Une chaîne de montage où chaque pièce passe de poste en poste, au lieu d'empiler toutes les pièces entre chaque poste.
function* naturels() { let n = 1; while (true) yield n++; }
const carresPairs = naturels()
.filter(n => n % 2 === 0)
.map(n => n * n)
.take(3)
.toArray(); // [4, 16, 36] — l'infini n'est jamais parcouru
// Map.values() sans copie en tableau
const total = stocks.values().reduce((a, b) => a + b, 0);Cas d'usage : Traiter des flux ou de grandes collections (Map, Set, générateurs) sans copies ; lire un générateur infini par morceaux.
Convention par laquelle un objet produit une séquence : il est itérable s'il expose [Symbol.iterator]() retournant un itérateur dont next() renvoie {value, done}. Depuis ES2025, les itérateurs natifs héritent de la classe globale Iterator et disposent des « iterator helpers » (map, filter, take, drop, flatMap, reduce, toArray…), et Iterator.concat arrive avec ES2026.
Un distributeur de tickets : chaque appel a next() te donne le ticket suivant, et done te dit quand il n'y en a plus.
const range = {
from: 1, to: 3,
[Symbol.iterator]() {
let n = this.from;
return { next: () => n <= this.to
? { value: n++, done: false }
: { done: true } };
}
};
for (const n of range) console.log(n);Cas d'usage : Rendre des objets maison utilisables dans for...of, spread et destructuring ; enchaîner des transformations paresseuses sans créer de tableaux intermédiaires.
Compilation Just-In-Time : V8 interprété d'abord le bytecode (Ignition), puis compile en code machine optimise (TurboFan) les fonctions chaudes. Peut desoptimiser si les hypothèses sont invalides.
Un cuisinier qui improvise la première fois (interprétation), puis écrit la recette (compilation) quand il a assez d'expérience avec le plat.
// V8 pipeline:
// 1. Parser -> AST
// 2. Ignition -> Bytecode (interprete)
// 3. Profiling (quelles fonctions sont chaudes?)
// 4. TurboFan -> Code machine optimise
// 5. Deopt si les types changentCas d'usage : Comprendre pourquoi le code JS est rapide malgré le typage dynamique, et comment éviter les deoptimisations.
Le scope d'une variable est déterminé par l'endroit ou elle est écrite dans le code source, pas par l'endroit ou la fonction est appelée. C'est la base des closures en JS.
Ton adresse postale dépend d'ou tu habites, pas d'ou tu te trouves quand tu reçois le courrier.
const x = 'global';
function foo() {
console.log(x); // 'global' (scope lexical)
}
function bar() {
const x = 'bar';
foo(); // affiche 'global', pas 'bar'
}Cas d'usage : Prédire le comportement des closures et comprendre pourquoi JS n'utilise pas le dynamic scoping.
Opérateurs &&=, ||= et ??= qui combinent affectation et logique. a ??= b assigne b a a seulement si a est null/undefined. Court-circuitage préserve.
Remplir un formulaire pre-rempli : tu n'écris que dans les cases vides (??=), pas celles déjà remplies.
let opts = {};
opts.timeout ??= 5000; // assigne si null/undefined
opts.debug ||= false; // assigne si falsy
opts.verbose &&= true; // assigne si truthyCas d'usage : Initialiser des options/configurations avec des valeurs par défaut de manière concise.
Collection clé-valeur ordonnée ou les clés peuvent être de n'importe quel type (objets, fonctions, primitives). Plus performante qu'un objet pour les ajouts/suppressions fréquents.
Un casier de vestiaire ou chaque casier a une clé unique de n'importe quelle forme, pas juste une étiquette texte.
const cache = new Map();
const key = { id: 1 };
cache.set(key, 'data');
cache.get(key); // 'data'
cache.has(key); // true
cache.size; // 1Cas d'usage : Cache en mémoire, compteurs de fréquences, lookup tables avec des clés non-string.
Proposition « Upsert » (Stage 4, listée par TC39 pour ES2026) : Map et WeakMap gagnent getOrInsert(clé, valeur) qui renvoie la valeur existante ou insère puis renvoie la valeur par défaut, et getOrInsertComputed(clé, fn) qui ne calcule la valeur que si la clé manque. Livrée dans V8 14.6, donc dans Node.js 26 (5 mai 2026) ; disponible dans les navigateurs majeurs depuis février 2026.
Le porte-manteau du restaurant : si votre crochet existe on vous le rend, sinon on en installe un et on vous le donne.
const parVille = new Map();
for (const client of clients) {
// Avant : if (!m.has(k)) m.set(k, []); m.get(k).push(...)
parVille.getOrInsert(client.ville, []).push(client);
}
// Calcul coûteux seulement si absent
const cache = new Map();
const r = cache.getOrInsertComputed(url, () => calculerLourd(url));Cas d'usage : Regroupements (multimap), caches mémoïsés, compteurs : le motif has/get/set en une ligne.
Algorithme de GC utilise par V8 : phase Mark parcourt le graphe d'objets depuis les racines (global, stack) et marque les atteignables. Phase Sweep libéré les non-marques.
Un inventaire d'entrepôt : tu coches (mark) tout ce qui est sur la liste de commandes, puis tu jettes (sweep) le reste.
// Racines GC: global, stack, registres
// Atteignable = survit
window.app = { data: [1,2,3] }; // atteignable via window
// Non atteignable = GC
function leak() {
const huge = new Array(1e6);
// huge est GC apres retour de leak()
}Cas d'usage : Comprendre pourquoi certains objets ne sont pas collectes et diagnostiquer les fuites mémoire.
Technique de cache qui stocke le résultat d'un appel de fonction base sur ses arguments. Si les mêmes arguments sont repasses, le résultat est retourne du cache sans recalcul.
Un carnet de notes : avant de recalculer, tu vérifies si tu as déjà note la réponse.
function memoize(fn) {
const cache = new Map();
return function(...args) {
const key = JSON.stringify(args);
if (cache.has(key)) return cache.get(key);
const result = fn.apply(this, args);
cache.set(key, result);
return result;
};
}Cas d'usage : Fonctions de calcul coûteux appelées fréquemment avec les mêmes paramètrès (fibonacci, selectors Redux).
Patterns courants de fuites mémoire : event listeners non retires, closures retenant de gros objets, références DOM détachées, timers oublies, caches non bornes.
Des robinets qui fuient dans la maison : individuellement c'est rien, mais au bout d'un mois la facture d'eau explose.
// Fuite: listener jamais retire
window.addEventListener('resize', handler);
// Fuite: closure retient tout le scope
function init() {
const bigData = new Array(1e6);
return () => console.log(bigData.length);
}
// Fix: retirer les listeners, nullifier les refsCas d'usage : Debugger les apps qui ralentissent avec le temps, onglets qui consomment de plus en plus de RAM.
File prioritaire qui contient les callbacks de Promises (.then/.catch/.finally), MutationObserver et queueMicrotask. Vidée entièrement avant chaque macrotask.
Les clients VIP qui passent devant tout le monde a chaque tour de service.
queueMicrotask(() => console.log('micro 1'));
setTimeout(() => console.log('macro'), 0);
queueMicrotask(() => console.log('micro 2'));
// micro 1, micro 2, macroCas d'usage : Exécuter du code juste après l'opération courante mais avant le prochain rendu ou timer.
API qui observe les changements du DOM (attributs, enfants, texte) de manière asynchrone et performante. Remplace les deprecated Mutation Events.
Une caméra de surveillance qui enregistre chaque modification dans une pièce et te fait un rapport groupe.
const observer = new MutationObserver((mutations) => {
mutations.forEach(m => console.log(m.type));
});
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true
});Cas d'usage : Détecter des modifications DOM par des scripts tiers, synchroniser un état externe avec le DOM.
Opérateur qui crée une instance : 1) créé un objet vide, 2) lie son [[Prototype]] au .prototype du constructeur, 3) exécuté le constructeur avec this = nouvel objet, 4) retourne l'objet.
Un moule a gâteau : new prend le moule (constructeur), verse la pâte (propriétés), et te donne un gâteau (instance).
function User(name) {
this.name = name;
}
User.prototype.hi = function() { return this.name; };
const u = new User('Alice');
u.hi(); // 'Alice'Cas d'usage : Instancier des objets a partir de constructeurs ou de classes ES6.
Modèle de permissions intégré à Node.js : lancé avec --permission, le processus se voit refuser (ERR_ACCESS_DENIED) l'accès au système de fichiers, aux processus enfants, aux workers, au réseau, aux addons natifs, à WASI et au FFI, sauf autorisation explicite (--allow-fs-read, --allow-fs-write, --allow-child-process, --allow-net…). Ajouté en 20.0.0 en expérimental, il est stable depuis 23.5.0 et 22.13.0 ; --permission-audit journalise les violations sans bloquer.
Un badge d'accès qui n'ouvre que les portes listées, plutôt qu'un passe-partout.
# Refuse tout sauf lecture de ./config et écriture de ./logs
node --permission \
--allow-fs-read=./config \
--allow-fs-write=./logs \
app.js
# Phase de découverte : journaliser sans bloquer
node --permission-audit --allow-fs-read=/tmp app.js
# Dans le code : process.permission.has('fs.write', './logs') → trueCas d'usage : Exécuter des scripts tiers, des dépendances peu fiables ou des workers d'IA avec un périmètre borné.
Framework de test intégré à Node.js : module node:test (stable depuis la 20.0.0) et commande node --test. Il fournit describe/it, sous-tests, mocks (fonctions, modules, timers), snapshots, mode --watch, couverture (--expérimental-test-coverage) et rapporteurs spec, tap, dot, junit, lcov. Depuis Node 24, il attend automatiquement les sous-tests sans await manuel.
La trousse de secours livrée avec la voiture : pas la plus complète, mais toujours là.
// math.test.mjs — lancé par : node --test
import { test, mock } from 'node:test';
import assert from 'node:assert/strict';
test('addition', () => {
assert.equal(1 + 1, 2);
});
test('mock', () => {
const fn = mock.fn(() => 42);
fn();
assert.equal(fn.mock.callCount(), 1);
});Cas d'usage : Bibliothèques et outils sans dépendance de test ; CI légère ; projets qui veulent éviter Jest ou Vitest.
Module SQLite intégré à Node.js, ajouté en 22.5.0, sorti du drapeau --expérimental-sqlite en 23.4.0 et 22.13.0, et passé « release candidate » (stabilité 1.2) en 25.7.0. API synchrone : DatabaseSync, prépare(), run/get/all/iterate, plus un SQLTagStore qui met en cache des requêtes écrites en template literal. Bun 1.4 annonce 100 % de compatibilité avec ce module.
Un carnet de comptes rangé dans le tiroir du bureau : pas besoin d'aller à la banque pour une addition.
import { DatabaseSync } from 'node:sqlite';
const db = new DatabaseSync('app.db'); // ou ':memory:'
db.exec('CREATE TABLE IF NOT EXISTS todo(id INTEGER PRIMARY KEY, txt TEXT) STRICT');
const ins = db.prepare('INSERT INTO todo (txt) VALUES (?)');
ins.run('acheter du pain');
const tous = db.prepare('SELECT * FROM todo').all();
console.log(tous); // [{ id: 1, txt: 'acheter du pain' }]
db.close();Cas d'usage : CLI, prototypes, caches locaux, tests : une base relationnelle sans dépendance native ni serveur.
Opérateur ?? qui retourne la valeur de droite uniquement si celle de gauche est null ou undefined (pas pour 0, '' ou false, contrairement a ||).
Un filet de sécurité qui ne se déclenche que si le trapéziste est vraiment absent (null/undefined), pas s'il est juste petit (0) ou silencieux ('').
const port = config.port ?? 3000;
// vs ||
0 || 3000; // 3000 (bug!)
0 ?? 3000; // 0 (correct)
'' ?? 'default'; // '' (correct)Cas d'usage : Définir des valeurs par défaut en préservant les valeurs falsy légitimes comme 0, '' ou false.
Méthodes statiques clés : Object.keys/values/entries (énumération), Object.assign (copie shallow), Object.freeze/seal (immutabilite), Object.fromEntries (reconstruction), Object.create (prototype).
La boite a outils officielle pour manipuler les objets : chaque outil a un usage précis.
const obj = { a: 1, b: 2 };
Object.keys(obj); // ['a', 'b']
Object.entries(obj); // [['a',1], ['b',2]]
const copy = Object.assign({}, obj);
const fromMap = Object.fromEntries(new Map([['x',1]]));Cas d'usage : Transformer, copier, geler ou iterer sur les propriétés d'un objet de manière standard.
Depuis ES2019, le paramètre du catch est optionnel. Utile quand l'erreur n'est pas nécessaire dans le traitement.
Savoir qu'il y a eu un problème sans avoir besoin de lire le rapport détaillé.
try {
JSON.parse(input);
} catch {
// pas besoin de (err)
return defaultValue;
}Cas d'usage : Cas ou on veut juste ignorer l'erreur et fournir un fallback sans logger.
Opérateur ?. qui court-circuite a undefined si la valeur a gauche est null/undefined. Fonctionne sur les propriétés, méthodes et accès dynamiques.
Frapper a une porte : si personne ne répond (?.), tu passes ton chemin au lieu de défoncer la porte (TypeError).
const city = user?.address?.city;
const result = obj?.method?.();
const val = arr?.[0]?.name;Cas d'usage : Accéder a des propriétés de données API incertaines sans multiplier les vérifications if.
Oxc (« JavaScript Oxidation Compiler ») est une chaîne d'outils en Rust : parseur, résolveur, transformeur, minifieur, formateur (Oxfmt) et linter (Oxlint). Oxlint embarque plus de 865 règles (ESLint, TypeScript, React, Jest, Vitest) et s'annonce 50 à 100 fois plus rapide qu'ESLint ; son analyse typée s'appuie sur tsgo, le port Go de TypeScript 7. Oxc est le compilateur de Rolldown et donc de Vite 8.
Un scanner d'aéroport qui traite toute la file en quelques secondes, au lieu d'ouvrir chaque valise à la main.
# Installer et lancer
pnpm add -D oxlint
npx oxlint . # règles par défaut, très rapide
# Migrer une config ESLint existante
npx @oxlint/migrate
# Cohabiter : ESLint ne garde que ce qu'Oxlint ne couvre pas
pnpm add -D eslint-plugin-oxlintCas d'usage : Grands monorepos et CI où ESLint devient le goulot ; pré-commit instantané ; cohérence avec la chaîne Vite/Rolldown.
Fixer un ou plusieurs arguments d'une fonction pour créer une nouvelle fonction avec moins de paramètrès. Contrairement au currying, on peut fixer plusieurs arguments d'un coup.
Pre-remplir une partie d'un formulaire : les champs fixes ne changent plus, tu ne remplis que le reste.
const multiply = (a, b) => a * b;
const double = multiply.bind(null, 2);
double(5); // 10
// Ou sans bind
const partial = (fn, ...fixed) =>
(...args) => fn(...fixed, ...args);Cas d'usage : Créer des variantes de fonctions utilitaires (logger avec prefix, requêtes avec base URL).
API qui observe les entrées de la Performance Timeline (paint, navigation, resource, longtask, etc.). Permet de collecter les métriques Web Vitals de manière non-bloquante.
Un chronomètre automatique qui enregistre les temps de chaque étape d'une course sans que les coureurs s'arrêtent.
const observer = new PerformanceObserver((list) => {
list.getEntries().forEach(entry => {
console.log(entry.name, entry.duration);
});
});
observer.observe({ type: 'largest-contentful-paint',
buffered: true });Cas d'usage : Mesurer LCP, FID, CLS en production, monitoring RUM (Real User Monitoring).
Champs de classe préfixes par # véritablement prives (hard private). Non accessibles en dehors de la classe, même par les sous-classes. Contrairement aux conventions _prefix.
Un coffre-fort dans ta chambre : même les membres de ta famille ne peuvent pas l'ouvrir.
class Counter {
#count = 0;
increment() { this.#count++; }
get value() { return this.#count; }
}
const c = new Counter();
c.increment();
c.value; // 1
// c.#count; // SyntaxErrorCas d'usage : Encapsulation stricte dans les classes, protection des invariants internes.
Objet représentant le résultat futur d'une opération asynchrone. Peut être pending, fulfilled ou rejected. Chainable via .then() et .catch().
Un ticket de pressing : tu deposes ton vêtement, tu reçois un ticket, et tu reviens le chercher quand c'est prêt (ou on te prévient si c'est perdu).
const getData = () => new Promise((resolve, reject) => {
setTimeout(() => resolve('data'), 100);
});
getData()
.then(data => console.log(data))
.catch(err => console.error(err));Cas d'usage : Gérer toute opération asynchrone : appels API, lecture de fichiers, timers.
Les rejections de Promise doivent être catchees avec .catch() ou try/catch avec await. Les rejections non gérées déclenchent unhandledrejection et peuvent crasher en Node.js.
Un filet sous le trapèze : sans lui (catch), la moindre chute (rejection) est fatale.
// Avec async/await
try {
const data = await fetchData();
} catch (err) {
handleError(err);
}
// Global fallback
window.addEventListener('unhandledrejection', (e) => {
reportError(e.reason);
});Cas d'usage : Toute chaîne de promesses doit avoir un catch terminal pour éviter les rejections silencieuses.
Combinateurs statiques de Promise : all (toutes réussies ou premier échec), allSettled (toutes terminées), race (première terminée), any (première réussie). Deux ajouts récents : Promise.withResolvers (ES2024) qui renvoie {promise, résolve, reject}, et Promise.try (ES2025) qui exécute une fonction synchrone ou asynchrone en capturant ses exceptions dans une promesse.
all = tous les invites doivent arriver pour manger. race = on mange des que le premier arrive. any = on mange des qu'un invite avec le dessert arrive. allSettled = on attend que tout le monde ait répondu, oui ou non.
const [a, b] = await Promise.all([fetchA(), fetchB()]);
const etats = await Promise.allSettled([p1, p2]);
const rapide = await Promise.race([p1, timeout(500)]);
const premier = await Promise.any([p1, p2]);
// ES2024 : résolveurs externes
const { promise, resolve } = Promise.withResolvers();
// ES2025 : capture aussi les throw synchrones
await Promise.try(() => JSON.parse(texte)).catch(console.error);Cas d'usage : Paralleliser des appels API indépendants (all), tolérant aux échecs (allSettled), timeout (race).
Méthode statique ES2025 qui appelle une fonction immédiatement et enveloppe son résultat dans une promesse : une valeur renvoyée donne une promesse déjà résolue, un throw synchrone une promesse rejetée, une promesse renvoyée est simplement suivie. Elle unifie ainsi le traitement des callbacks synchrones et asynchrones. Disponible dans les navigateurs majeurs depuis janvier 2025.
Un filet de sécurité tendu avant le saut, que le trapéziste tombe tout de suite ou plus tard.
function executer(action) {
return Promise.try(action)
.then(r => console.log('ok', r))
.catch(e => console.error('erreur', e.message));
}
executer(() => 'sync'); // ok sync
executer(() => { throw new Error('x'); }); // erreur x (pas de crash)
executer(async () => 'async'); // ok async
// Avant : Promise.resolve().then(fn) retardait fn d'un tickCas d'usage : Wrappers de plugins ou de hooks utilisateur dont on ne sait pas s'ils sont async ; débuts de chaînés de promesses.
Méthode statique ES2024 qui renvoie un objet {promise, résolve, reject} : la promesse et ses fonctions de règlement vivent dans le même scope, sans passer par le constructeur et ses variables externes. Disponible partout depuis mars 2024 (Baseline).
Recevoir la boîte et la clé en même temps, plutôt que de devoir fabriquer la clé depuis l'intérieur de la boîte.
// File d'attente : on résout plus tard, depuis un autre événement
const { promise, resolve, reject } = Promise.withResolvers();
bouton.addEventListener('click', () => resolve('cliqué'), { once: true });
setTimeout(() => reject(new Error('délai')), 5000);
console.log(await promise);
// Avant : let res; const p = new Promise(r => { res = r; });Cas d'usage : Ponts événement → promesse, files de messages, itérateurs asynchrones alimentés de l'extérieur.
Modèle d'héritage de JS ou les objets héritent directement d'autres objets via la prototype chain, contrairement a l'héritage classique par classes. Les classes ES6 sont du sucre syntaxique dessus.
Photocopier un document et modifier la copie : l'original reste intact, et tu peux toujours te référer a lui.
function Vehicle(type) { this.type = type; }
Vehicle.prototype.describe = function() {
return `I am a ${this.type}`;
};
const car = new Vehicle('car');
car.describe(); // 'I am a car'Cas d'usage : Créer des hiérarchies d'objets légères sans le coût d'un système de classes complet.
Chaîne de prototypes par laquelle JS recherche les propriétés et méthodes. Chaque objet a un [[Prototype]] interne qui pointe vers un autre objet, jusqu'a null.
L'arbre généalogique : si tu ne sais pas cuisiner, tu demandes a ta mère, puis a ta grand-mère, en remontant les générations.
const animal = { eat() { return true; } };
const dog = Object.create(animal);
dog.bark = () => 'Woof';
dog.eat(); // true (remonte la chaine)
dog.bark(); // 'Woof' (propre)Cas d'usage : Comprendre l'héritage en JS, le fonctionnement de class/extends, et optimiser la recherche de propriétés.
Objet qui encapsulé un autre objet et intercepte les opérations fondamentales (get, set, has, delete, etc.) via des traps. Base de la réactivité dans Vue 3 et des ORMs modernes.
Un secrétaire personnel qui intercepte tous tes appels et courriers, et peut les modifier avant de te les transmettre.
const handler = {
get(target, key) {
console.log(`Reading ${key}`);
return target[key];
},
set(target, key, value) {
console.log(`Setting ${key}=${value}`);
target[key] = value;
return true;
}
};
const proxy = new Proxy({}, handler);Cas d'usage : Systèmes réactifs (Vue 3), validation automatique, logging transparent, mocking en tests.
Fonction qui retourne toujours le même résultat pour les mêmes arguments et ne produit aucun effet de bord. Déterministe et sans mutation d'état externe.
Une calculatrice : 2+3 donne toujours 5, peu importe quand ou ou tu fais le calcul.
// Pure
const add = (a, b) => a + b;
const upper = (s) => s.toUpperCase();
// Impure
let count = 0;
const increment = () => ++count; // mutation externeCas d'usage : Reducers Redux, fonctions de transformation, tests unitaires faciles, memoization possible.
Fonction globale qui ajoute un callback a la microtask queue. Plus léger que Promise.résolve().then() pour planifier une microtask.
Glisser un post-it urgent sur la pile 'a traiter immédiatement' au lieu de créer un ticket formel (Promise).
console.log('1');
queueMicrotask(() => console.log('2'));
console.log('3');
// 1, 3, 2Cas d'usage : Différer une action après le code synchrone courant mais avant le prochain rendu.
Objet built-in fournissant des méthodes statiques pour les opérations interceptables par Proxy. Miroir 1:1 des traps de Proxy avec des retours booléens au lieu d'exceptions.
Le mode d'emploi officiel des opérations JS : au lieu de bidouiller, tu utilises la méthode standard.
const obj = { x: 1 };
Reflect.get(obj, 'x'); // 1
Reflect.set(obj, 'y', 2); // true
Reflect.has(obj, 'x'); // true
Reflect.ownKeys(obj); // ['x', 'y']Cas d'usage : Toujours utiliser Reflect dans les traps de Proxy pour le comportement par défaut correct.
Modificateurs inline standardisés dans ES2025 : (?i:motif), (?m:motif), (?s:motif) activent un drapeau sur une portion seulement, et (?-i:motif) le désactive. Seuls i, m et s sont autorisés ; g, y, u, v et d restent globaux. Disponible dans les navigateurs majeurs depuis septembre 2025 (Baseline 2025).
Un interrupteur local dans une pièce, plutôt que le disjoncteur général de la maison.
// 'hello' insensible à la casse, 'World' sensible
const re = /(?i:hello) World/;
re.test('HELLO World'); // true
re.test('hello world'); // false
// Désactiver m localement dans une regex multi-lignes
const front = /(?-m:^)---\n^title:.*$/ms;Cas d'usage : Grammaires, lexers, validations où une seule partie du motif doit ignorer la casse.
Méthode statique (ES2025) qui échappe tous les caractères spéciaux d'une chaîne afin de l'insérer telle quelle dans un motif construit avec new RegExp. Elle protège aussi les ponctuations et le premier caractère alphanumérique (\x66oo). Disponible dans les navigateurs majeurs depuis mai 2025 (Baseline 2025) ; ajoutée aux types TypeScript en 6.0.
Mettre des guillemets autour d'une recherche Google pour qu'elle soit prise au mot.
const domaine = 'developer.mozilla.org';
// Sans escape, le point matche n'importe quel caractère
const re = new RegExp(`https?://${RegExp.escape(domaine)}(?=/)`, 'g');
re.test('https://developer.mozilla.org/fr'); // true
re.test('https://developerXmozilla.org/fr'); // false
RegExp.escape('a+b?'); // '\\x61\\+b\\?'Cas d'usage : Recherche utilisateur injectée dans une regex, filtres dynamiques, remplacement littéral.
API qui planifie un callback avant le prochain repaint du navigateur (~60fps). Synchronise les animations avec le cycle de rendu pour des animations fluides.
Attendre le signal du métronome avant de jouer la note suivante : tout reste synchronise avec le rythme d'affichage.
function animate(timestamp) {
element.style.transform =
`translateX(${timestamp / 10}px)`;
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);Cas d'usage : Animations JS fluides, canvas rendering, synchronisation avec le cycle de repaint.
API qui planifie un callback pendant les périodes d'inactivité du navigateur. Reçoit un IdleDeadline indiquant le temps restant. Idéal pour les taches non-urgentes.
Faire le ménage pendant les pubs a la télé : tu profites des pauses naturelles sans interrompre le programme.
requestIdleCallback((deadline) => {
while (deadline.timeRemaining() > 0 && tasks.length) {
processTask(tasks.pop());
}
if (tasks.length) requestIdleCallback(cb);
}, { timeout: 2000 });Cas d'usage : Analytics, prefetching, taches de fond non-critiques, warm-up de cache.
Capacité de Node.js à charger un module ESM depuis CommonJS avec require(). Ajoutée en 22.0.0 et 20.17.0 derrière un drapeau, activée par défaut en 22.12.0 et 20.19.0, elle est stable depuis 25.4.0. Condition : le module ESM ne doit pas contenir de top-level await (sinon ERR_REQUIRE_ASYNC_MODULE). TypeScript 5.8 (28 février 2025) la modélise avec --module nodenext.
Une porte enfin percée entre deux immeubles mitoyens : on passe d'un côté à l'autre sans faire le tour du pâté de maisons.
// utils.mjs
export function slug(s) { return s.toLowerCase().replace(/\s+/g, '-'); }
// legacy.cjs — Node 22.12+/20.19+
const { slug } = require('./utils.mjs');
console.log(slug('Hello World')); // hello-world
// Détection : process.features.require_module === true
// Diagnostic d'un TLA bloquant : --experimental-print-required-tlaCas d'usage : Consommer une dépendance publiée en ESM seul depuis une base CommonJS ; simplifier la publication des bibliothèques.
API qui observe les changements de taille d'un élément DOM. Appelle le callback quand les dimensions changent, sans dépendre du resize de la fenêtre.
Un mètre automatique colle sur un meuble qui t'alerte des que les dimensions changent.
const observer = new ResizeObserver((entries) => {
for (const entry of entries) {
const { width, height } = entry.contentRect;
console.log(`${width}x${height}`);
}
});
observer.observe(document.querySelector('.chart'));Cas d'usage : Graphiques responsifs, conteneurs flexibles, composants qui s'adaptent a leur taille.
Chaîne de références entre les scopes imbriques qui permet a une fonction d'accéder aux variables de ses scopes parents. La recherche remonte la chaîne jusqu'au scope global.
Chercher un livre dans ta chambre, puis le salon, puis la bibliothèque municipale : tu remontes les niveaux jusqu'a trouver.
const global = 'G';
function outer() {
const mid = 'M';
function inner() {
const local = 'L';
console.log(global, mid, local); // G M L
}
inner();
}Cas d'usage : Comprendre la résolution des variables et éviter les collisions de noms entre scopes imbriques.
Proxy programmable entre l'app et le réseau, tournant en arrière-plan. Intercepte les requêtes fetch pour implémenter du cache offline, des push notifications et la synchronisation en arrière-plan.
Un concierge d'hôtel qui intercepte ton courrier : il peut te le remettre du stock (cache) sans appeler le facteur (réseau).
// sw.js
self.addEventListener('fetch', (e) => {
e.respondWith(
caches.match(e.request)
.then(cached => cached || fetch(e.request))
);
});
// Registration
navigator.serviceWorker.register('/sw.js');Cas d'usage : PWA offline-first, cache intelligent, push notifications, background sync.
Collection de valeurs uniques, itérable et ordonnée par insertion ; un doublon ajouté est ignoré. ES2025 a ajouté sept méthodes ensemblistes : union, intersection, différence, symmetricDifference, isSubsetOf, isSupersetOf et isDisjointFrom, disponibles dans tous les navigateurs majeurs depuis juin 2024 (Baseline 2024).
Un tampon encreur qui marque les invites a l'entrée : même si tu te représentes, tu n'es compte qu'une fois.
const a = new Set([1, 2, 2, 3]); // Set {1, 2, 3}
a.has(2); // true
[...new Set(tableau)]; // dédoublonnage
// ES2025
const b = new Set([3, 4]);
a.union(b); // Set {1, 2, 3, 4}
a.intersection(b); // Set {3}
a.isDisjointFrom(new Set([9])); // trueCas d'usage : Deduplication de tableaux, tracking d'éléments uniques, vérification d'appartenance O(1).
Sept méthodes ensemblistes ajoutées à Set par ES2025 : union, intersection, différence, symmetricDifference, isSubsetOf, isSupersetOf et isDisjointFrom. Elles renvoient un nouveau Set (ou un booléen) et acceptent tout objet « set-like » exposant size, has et keys. Disponibles dans tous les navigateurs majeurs depuis juin 2024 (Baseline 2024) et dans TypeScript depuis la 5.5.
Les diagrammes de Venn du collège, enfin disponibles en une ligne.
const admins = new Set(['ana', 'bob']);
const actifs = new Set(['bob', 'chloe']);
admins.union(actifs); // Set {ana, bob, chloe}
admins.intersection(actifs); // Set {bob}
admins.difference(actifs); // Set {ana}
admins.symmetricDifference(actifs); // Set {ana, chloe}
new Set(['bob']).isSubsetOf(admins); // true
admins.isDisjointFrom(new Set(['zoe'])); // trueCas d'usage : Droits d'accès, comparaison de tags, détection de doublons entre deux listes sans boucles manuelles.
Toute modification d'état observable en dehors de la fonction : mutation de variable globale, écriture DOM, appel réseau, console.log, modification d'arguments. L'oppose d'une pure function.
Laisser des miettes sur la table en mangeant : tu as fait ton action (manger) mais tu as aussi change l'environnement.
// Side effects
let total = 0;
function addToTotal(n) {
total += n; // mutation globale
console.log(total); // I/O
document.title = n; // DOM
}Cas d'usage : Nécessaires en pratique (I/O, DOM, API), mais a isoler et contrôler dans des couches dédiées.
Code exécuté a l'import d'un module (polyfills, CSS imports, enregistrement global). Le champ sideEffects dans package.json indique au bundler quels fichiers ont des effets de bord.
Un colis piège : juste en l'ouvrant (import), quelque chose se déclenche automatiquement.
// polyfill.js (side effect)
import 'core-js/stable';
// package.json
{
"sideEffects": ["*.css", "./src/polyfills.js"]
}
// false = aucun side effect, tree shaking totalCas d'usage : Déclarer correctement sideEffects pour permettre un tree shaking optimal par le bundler.
L'opérateur ... sert de spread (étaler un iterable) ou rest (collecter les arguments restants). Spread copie superficiellement, rest regroupe dans un tableau.
Spread = étaler les cartes sur la table. Rest = ramasser toutes les cartes restantes en un paquet.
// Spread
const merged = { ...obj1, ...obj2 };
const copy = [...array];
// Rest
function sum(...nums) {
return nums.reduce((a, b) => a + b, 0);
}Cas d'usage : Copier/fusionner objets et tableaux de manière immutable, collecter des arguments variadiques.
stopPropagation empêche l'evenement de remonter/descendre aux parents mais exécute les autres listeners du même élément. stopImmediatePropagation arrête aussi les listeners suivants sur le même élément.
stopPropagation = fermer la porte de ta chambre (les voisins n'entendent plus). stopImmediate = aussi couper le son dans ta chambre (même toi tu n'entends plus).
el.addEventListener('click', (e) => {
e.stopPropagation(); // parent ne recoit pas
});
el.addEventListener('click', (e) => {
e.stopImmediatePropagation();
// les listeners suivants sur el sont aussi stoppes
});Cas d'usage : Empêcher un modal de se fermer quand on clique a l'intérieur, isoler des composants.
API pour traiter des données en flux (ReadableStream, WritableStream, TransformStream). Permet de consommer des données chunk par chunk sans tout charger en mémoire.
Un tuyau d'arrosage : l'eau (données) coule en continu au lieu d'être livrée en citerne entière.
const response = await fetch('/big-file');
const reader = response.body.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
process(value); // Uint8Array chunk
}Cas d'usage : Télécharger des gros fichiers avec progression, streaming SSE/LLM, traitement vidéo/audio.
Mode d'exécution plus strict active par 'use strict' ou implicitement dans les modules ESM. Interdit les variables non déclarées, les doublons de params, et rend this undefined dans les fonctions simples.
Le mode examen : plus de copier-coller, plus de brouillon, chaque erreur est signalée immédiatement.
'use strict';
x = 5; // ReferenceError
delete Object.prototype; // TypeError
function f() { return this; } // undefinedCas d'usage : Actif par défaut dans les modules ESM et les classes. Attrape les erreurs silencieuses tôt.
API globale structuredClone() qui crée une copie profonde d'un objet, supportant les types complexes (Date, Map, Set, ArrayBuffer, etc.). Remplace JSON.parse(JSON.stringify()).
Une photocopieuse couleur haute fidélité qui reproduit chaque détail, contrairement a une photocopie noir et blanc (JSON).
const original = {
date: new Date(),
data: new Map([['a', 1]]),
nested: { arr: [1, 2] }
};
const clone = structuredClone(original);
clone.nested.arr.push(3);
// original.nested.arr inchangeCas d'usage : Deep clone d'états complexes, transfert de données entre workers, copie d'objets avec types spéciaux.
JSON.parse(JSON.stringify()) perd les Date, Map, Set, undefined, fonctions et références circulaires. structuredClone gère tout sauf les fonctions et le DOM. Toujours préférer structuredClone.
JSON = scanner un document en noir et blanc (perd les couleurs). structuredClone = photocopier en couleur haute fidélité.
const obj = { d: new Date(), m: new Map([['a',1]]) };
// JSON perd tout
JSON.parse(JSON.stringify(obj));
// { d: '2024-...', m: {} }
// structuredClone preserve
structuredClone(obj);
// { d: Date, m: Map }Cas d'usage : Deep clone d'états complexes avec des types non-JSON.
Type primitif unique et immutable créé par Symbol(). Utilise comme clé de propriété pour éviter les collisions. Les well-known symbols (Symbol.iterator, etc.) customisent le comportement du langage.
Un numéro de série unique grave sur une clé : même si deux clés se ressemblent, leurs numéros sont différents.
const id = Symbol('id');
const user = { [id]: 123, name: 'Alice' };
user[id]; // 123
Object.keys(user); // ['name'] (symbol invisible)
// Well-known
class Range {
*[Symbol.iterator]() { yield 1; yield 2; }
}Cas d'usage : Créer des propriétés privées-like, définir des protocoles (iterator), éviter les collisions de noms en libs.
Fonction appelée avec un template literal comme argument. Reçoit les parties statiques et les valeurs interpolées séparément, permettant un traitement personnalise.
Un traducteur qui reçoit la phrase avec des trous et les mots a insérer, et peut modifier chaque mot avant de reconstruire la phrase.
function highlight(strings, ...values) {
return strings.reduce((acc, str, i) =>
`${acc}${str}<b>${values[i] ?? ''}</b>`, '');
}
const name = 'Alice';
highlight`Hello ${name}!`;
// 'Hello <b>Alice</b>!'Cas d'usage : Sanitisation HTML (lit-html), CSS-in-JS (styled-components), SQL sécurisé, i18n.
Pattern ou un champ commun (type, kind) distingue les variantes d'un objet. Permet un pattern matching exhaustif et du code type-safe. Fondamental en TypeScript.
Des colis avec une étiquette de couleur : bleu = fragile, rouge = urgent. L'étiquette déterminé le traitement.
function handle(action) {
switch (action.type) {
case 'add': return state + action.value;
case 'reset': return 0;
default: throw new Error(`Unknown: ${action.type}`);
}
}
handle({ type: 'add', value: 5 });Cas d'usage : Reducers Redux, state machines, gestion d'evenements, API responses.
Terme générique pour la file de macrotasks (setTimeout, setInterval, I/O). Synonyme de Callback Queue dans la spec HTML. Un seul macrotask est traite par tour d'event loop.
La liste des corvées a faire une par une : après chaque corvée, tu vérifies s'il y a un message urgent (microtask).
// Un macrotask par tour de boucle
setTimeout(() => console.log('task 1'), 0);
setTimeout(() => console.log('task 2'), 0);
// Entre task 1 et task 2, les microtasks sont videesCas d'usage : Décomposer un traitement lourd en petits morceaux via setTimeout pour ne pas bloquer le thread principal.
Chaînés délimitées par des backticks (`) supportant l'interpolation ${expression}, le multi-ligne et les tagged templates. Remplacent la concatenation classique.
Un formulaire avec des champs a remplir : les ${} sont les cases vides ou JS inséré les valeurs.
const name = 'World';
const greeting = `Hello, ${name}!`;
const multiline = `
Line 1
Line 2
`;Cas d'usage : Construire des chaînés dynamiques, des requêtes SQL paramétrées (via tagged templates), du HTML.
API de dates et heures conçue pour remplacer Date : objets immuables, fuseaux horaires explicites, précision à la nanoseconde, calendriers multiples. La proposition est au Stage 4 et figure dans la liste TC39 des propositions attendues pour ES2027. Elle est livrée dans Firefox 139 (27 mai 2025), Chrome 144 (13 janvier 2026) et Node.js 26 (5 mai 2026) ; Safari est encore en développement.
Un agenda qui sait qu'un rendez-vous à 9 h à Paris n'est pas à 9 h à Tokyo, au lieu d'une simple horloge murale.
// Node 26+, Chrome 144+, Firefox 139+
const maintenant = Temporal.Now.instant();
const date = Temporal.PlainDate.from('2026-09-27');
const rdv = date.toPlainDateTime('14:30')
.toZonedDateTime('Europe/Paris');
const dans30j = rdv.add({ days: 30 }); // immuable : nouvel objet
const duree = rdv.until(dans30j); // Temporal.Duration
console.log(duree.days); // 30Cas d'usage : Réservations, facturation, planification multi-fuseaux : partout où Date et ses décalages implicites causent des bugs.
Zone entre le début du scope et la déclaration let/const ou la variable existe mais est inaccessible. Toute tentative d'accès lance un ReferenceError.
Un colis en transit : il a été expédié (hoiste) mais tu ne peux pas l'ouvrir tant qu'il n'est pas livre (déclaration).
{
// TDZ pour x commence ici
console.log(x); // ReferenceError!
// TDZ pour x finit ici
let x = 42;
console.log(x); // 42
}Cas d'usage : Comprendre pourquoi let/const est plus sur que var et debugger les ReferenceError.
Référence au contexte d'exécution courant. Sa valeur dépend de comment la fonction est appelée : méthode (objet), constructeur (nouvelle instance), arrow function (this lexical), ou appel simple (undefined en strict).
Le pronom 'je' : sa signification change selon qui parle, pas selon ou la phrase est écrite.
const obj = {
name: 'Alice',
greet() { return this.name; }, // 'Alice'
arrow: () => this.name, // undefined (this lexical)
};
const fn = obj.greet;
fn(); // undefined (contexte perdu)Cas d'usage : Accéder aux propriétés de l'objet courant dans les méthodes de classe ou les callbacks.
Limite l'exécution d'une fonction a maximum une fois par intervalle de temps. Contrairement au debounce, garantit une exécution régulière pendant une rafale d'appels.
Un robinet a débit contrôle : même si tu l'ouvres a fond, l'eau coule toujours a la même vitesse.
function throttle(fn, ms) {
let last = 0;
return function(...args) {
const now = Date.now();
if (now - last >= ms) {
last = now;
fn.apply(this, args);
}
};
}Cas d'usage : Scroll handler, mousemove tracking, rate limiting d'appels API cote client.
Permet d'utiliser await directement au niveau module (ESM) sans wrapper async. Le module devient asynchrone et les modules qui l'importent attendent sa résolution.
Pouvoir commander directement au drive-in sans devoir d'abord entrer dans le restaurant (la fonction async).
// config.mjs (ESM)
const res = await fetch('/config.json');
export const config = await res.json();
// app.mjs
import { config } from './config.mjs';
// config est deja resolue iciCas d'usage : Charger une configuration ou initialiser une connexion BD au démarrage d'un module ESM.
Transformations composables et indépendantes du type de collection. Combine map, filter, reduce en un seul passage sans créer de tableaux intermédiaires.
Un ouvrier polyvalent sur une chaîne de montage qui fait tri + transformation + emballage en un seul passage au lieu de trois passages séparés.
const map = f => step => (acc, x) => step(acc, f(x));
const filter = pred => step => (acc, x) =>
pred(x) ? step(acc, x) : acc;
const xform = [filter(x => x % 2), map(x => x * 10)];
const transduce = xform.reduceRight(
(s, fn) => fn(s), (acc, x) => [...acc, x]
);Cas d'usage : Traitement de grands jeux de données en un seul passage, éviter les allocations intermédiaires.
Élimination du code mort par les bundlers grâce à l'analyse statique des imports ESM : seuls les exports réellement importés restent dans le bundle. Outils actuels : Rollup, esbuild, webpack et Rolldown, le bundler Rust qui remplace le duo esbuild + Rollup dans Vite 8 (12 mars 2026) avec des builds annoncés 10 à 30 fois plus rapides.
Secouer un arbre pour ne garder que les fruits murs (code utilise) et laisser tomber les feuilles mortes (code inutilisé).
// utils.js
export const used = () => 'kept';
export const unused = () => 'removed';
// app.js
import { used } from './utils';
// unused est elimine du bundleCas d'usage : Réduire la taille des bundles en production, surtout avec de grosses librairies comme lodash.
Node.js exécute directement un fichier .ts en effaçant les annotations de type sans les vérifier. Activé par défaut depuis 23.6.0 et 22.18.0, déclaré stable en 25.2.0 et 24.12.0 ; Node 26 supprime --expérimental-transform-types. Seule la syntaxe effaçable passe : enum, namespace avec code, propriétés de paramètre, import = et décorateurs lèvent ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX. L'option TypeScript --erasableSyntaxOnly garantit la compatibilité.
Un correcteur qui gomme les annotations au crayon avant de rendre la copie, sans relire le fond.
// serveur.ts — lancé par : node serveur.ts (Node 24.12+/25.2+)
import type { IncomingMessage } from 'node:http'; // 'type' obligatoire
import { createServer } from 'node:http';
const port: number = 3000;
createServer((req: IncomingMessage, res) => {
res.end(`ok ${req.url}`);
}).listen(port);
// Interdit ici : enum, namespace avec code, constructor(private x)Cas d'usage : Scripts, outils internes et serveurs simples en TypeScript sans étape de build ; tsc reste utile pour vérifier les types en CI.
Proposition Stage 4 (listée par TC39 pour ES2026) qui ajoute Uint8Array.fromBase64, toBase64, fromHex, toHex et setFromBase64 : conversion directe entre octets et texte, sans passer par btoa/atob et leurs chaînés binaires. Options : alphabet 'base64' ou 'base64url', omitPadding. Disponible dans les navigateurs majeurs depuis septembre 2025 (Baseline 2025).
Un adaptateur de prise universel : les octets voyagent en texte sans bricolage.
const octets = new Uint8Array([29, 233, 101, 161]);
octets.toBase64(); // 'HelloQ=='
octets.toBase64({ alphabet: 'base64url', omitPadding: true }); // 'HelloQ'
octets.toHex(); // '1de965a1'
Uint8Array.fromBase64('HelloQ=='); // Uint8Array(4)
// Avant : btoa(String.fromCharCode(...octets)) — fragile et lentCas d'usage : Jetons dans une URL, clés WebCrypto, transport binaire en JSON, empreintes hexadécimales.
Vite 8 (12 mars 2026) remplace le duo esbuild (développement) + Rollup (production) par Rolldown, bundler écrit en Rust et compatible avec l'API des plugins Rollup, épaulé par le compilateur Oxc pour parser, transformer et minifier. Gains annoncés : builds 10 à 30 fois plus rapides (Linear : 46 s → 6 s). Node.js 20.19+ ou 22.12+ requis ; Vite 8.1 est sorti le 23 juin 2026.
Remplacer deux moteurs de marques différentes par un seul bloc : moins de pièces, mêmes commandes.
// vite.config.js — même API, moteur Rolldown
import { defineConfig } from 'vite';
export default defineConfig({
build: {
rolldownOptions: { // remplace rollupOptions
output: { manualChunks: { vendor: ['react', 'react-dom'] } },
},
},
});
// Chemins tsconfig « paths » résolus nativement, sans pluginCas d'usage : Applications front (React, Vue, Svelte…), SSR, bibliothèques : la chaîne de build la plus répandue de l'écosystème.
Map dont les clés sont obligatoirement des objets et sont tenues faiblement : si plus aucune référence forte n'existe vers la clé, l'entrée est garbage-collectée. Non iterable.
Des post-it colles sur des objets : quand l'objet part a la poubelle, le post-it disparaît avec.
const metadata = new WeakMap();
let user = { name: 'Alice' };
metadata.set(user, { visits: 0 });
// user = null -> l'entree est GC-eeCas d'usage : Stocker des metadonnees privées sur des objets sans empêcher leur garbage collection.
Référence faible vers un objet qui n'empêche pas sa garbage collection. Accès via .deref() qui retourne l'objet ou undefined s'il a été GC.
Prendre une photo d'un objet au lieu de le garder : tu peux regarder la photo, mais l'objet peut avoir été jeté entre-temps.
let obj = { data: 'important' };
const ref = new WeakRef(obj);
obj = null; // eligible au GC
// Plus tard
const derefed = ref.deref();
if (derefed) console.log(derefed.data);
else console.log('GC collected');Cas d'usage : Caches non-bloquants, observateurs légers, références optionnelles a des objets DOM.
Set dont les valeurs sont obligatoirement des objets tenus faiblement. Non iterable, non denombraable. Utile pour marquer des objets sans empêcher leur GC.
Une liste noire invisible : tu sais si quelqu'un y est, mais tu ne peux pas la consulter en entier.
const visited = new WeakSet();
function process(obj) {
if (visited.has(obj)) return;
visited.add(obj);
// traitement...
}Cas d'usage : Détecter les références circulaires, marquer les noeuds DOM déjà traites.
API de communication bidirectionnelle persistante entre client et serveur via le protocole ws://. Permet l'envoi et la réception de messages en temps réel sans polling.
Un téléphone : une fois la ligne ouverte, les deux cotes peuvent parler quand ils veulent, sans raccrocher et rappeler.
const ws = new WebSocket('wss://api.example.com');
ws.onopen = () => ws.send('Hello');
ws.onmessage = (e) => console.log(e.data);
ws.onerror = (e) => console.error(e);
ws.onclose = () => console.log('Closed');Cas d'usage : Chat en temps réel, notifications live, trading, jeux multijoueur, dashboards temps réel.
API permettant d'exécuter du JS dans un thread sépare du thread principal. Communiquent via postMessage/onmessage. N'ont pas accès au DOM.
Un assistant dans un bureau sépare : tu lui envoies du travail par pneumatique (postMessage), il te renvoie le résultat.
// main.js
const worker = new Worker('worker.js');
worker.postMessage({ data: bigArray });
worker.onmessage = (e) => console.log(e.data);
// worker.js
onmessage = (e) => {
const result = heavyCompute(e.data);
postMessage(result);
};Cas d'usage : Calculs lourds (crypto, parsing), traitement d'images, opérations qui bloqueraient le thread UI.