API pour annuler des operations asynchrones (fetch, event listeners, streams). Cree un signal qui peut etre passe a n'importe quelle API supportant l'annulation.
Un bouton d'arret d'urgence : tu peux stopper une operation 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 requetes fetch, annulation lors du demontage d'un composant React, cleanup de listeners.
Methodes 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 etape 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 donnees, filtrage de listes, calculs d'aggregation, recherche.
Zone de memoire brute de taille fixe, non redimensionnable. Accessible via des TypedArrays (Uint8Array, Float32Array, etc.) ou DataView pour lire/ecrire des donnees binaires.
Un terrain vague cloture : il existe en memoire, 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 possede ni son propre this, ni arguments, ni super. Le this est herite 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, methodes de tableaux (map, filter), quand on veut capturer le this du parent.
Sucre syntaxique sur les Promises. async declare une fonction retournant une Promise, await suspend l'execution jusqu'a la resolution. Rend le code asynchrone lisible comme du synchrone.
Commander un cafe et attendre au comptoir : tu ne fais rien d'autre en attendant (await), mais le reste du cafe (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 : Ecrire du code asynchrone lisible pour les appels API, acces BD, operations fichiers.
Fonction async function* combinant generateurs et async/await. Peut yield des valeurs de maniere asynchrone, consommable via for await...of.
Un chef qui prepare les plats un par un (yield) en attendant chaque ingredient 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 periodique, lecture de flux reseau, traitement de files de messages.
Protocole pour iterer sur des sequences asynchrones. L'objet implemente [Symbol.asyncIterator]() et next() retourne une Promise de {value, done}. Utilisable avec for await...of.
Un podcast en streaming : chaque episode arrive de maniere asynchrone, et tu les ecoutes 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 donnees en flux.
Objet global fournissant des operations atomiques sur les SharedArrayBuffer : load, store, add, sub, and, or, xor, wait, notify. Garantit l'integrite en contexte multithread.
Un tour de parole officiel : chaque personne attend son tour pour parler (wait/notify) et ses mots sont enregistres sans interruption (operations 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 representer des entiers de taille arbitraire, au-dela de Number.MAX_SAFE_INTEGER (2^53 - 1). Cree avec le suffixe n ou BigInt().
Un cahier avec un nombre illimite de pages pour ecrire des nombres, contrairement a une calculatrice a ecran 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 donnees 64-bit, calculs financiers de precision, cryptographie.
Methodes de Function.prototype pour controler this. call(ctx, ...args) et apply(ctx, [args]) appellent immediatement. bind(ctx, ...args) retourne une nouvelle fonction avec this lie.
call = telephoner a quelqu'un maintenant. apply = idem mais tu lis la liste des courses. bind = enregistrer le numero 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 methodes d'un autre objet, partial application.
API de communication entre contextes de meme origine (onglets, iframes, workers). Plus simple que SharedWorker pour du broadcast de messages.
Une radio interne d'entreprise : tous les bureaux (onglets) branchees sur la meme frequence recoivent 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.
Pile LIFO (Last In, First Out) qui trace les contextes d'execution des fonctions en cours. Chaque appel de fonction empile un frame, chaque return le depile.
Une pile d'assiettes : tu poses la derniere 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 depassements de pile (stack overflow).
File d'attente (macrotask queue) ou sont places les callbacks de setTimeout, setInterval, I/O et evenements DOM. Traites apres que la call stack et la microtask queue sont vides.
La file d'attente normale a la poste : tu passes apres 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 grace 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 : Detecter et casser les cycles avec des outils comme madge ou eslint-plugin-import.
Fonction qui capture et retient les variables de son scope parent meme apres que celui-ci a termine son execution. C'est le mecanisme fondamental derriere les callbacks, modules et data privacy en JS.
Un sac a dos que tu emportes en quittant la maison : meme loin de chez toi, tu as toujours acces 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 etat prive dans un module ou creer des fonctions factory avec configuration injectee.
CommonJS (require/module.exports) est synchrone, dynamique et utilise par Node.js historiquement. ESM (import/export) est statique, asynchrone, supportant le tree shaking. ESM est le standard moderne.
CommonJS = commander par telephone (dynamique, a la demande). ESM = liste de courses pre-ecrite (statique, analysable a l'avance).
// CommonJS
const fs = require('fs');
module.exports = { readFile: fs.readFile };
// ESM
import { readFile } from 'fs';
export { readFile };Cas d'usage : Choisir le bon systeme de modules selon le contexte : ESM pour le nouveau code, CommonJS pour la compatibilite Node.js legacy.
Compose enchaine des fonctions de droite a gauche, pipe de gauche a droite. Chaque fonction recoit le resultat de la precedente. Fondamental en programmation fonctionnelle.
Une chaine 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 donnees 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 etapes : chaque page collecte une info, et le formulaire n'est soumis qu'a la derniere etape.
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, creation de variantes specialisees, composition fonctionnelle.
Retarde l'execution d'une fonction jusqu'a ce qu'un delai se soit ecoule sans nouvel appel. Chaque appel reinitialise le timer. N'execute 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 reel (attendre que l'utilisateur arrete de taper), resize handler, auto-save.
Syntaxe ES6 pour extraire des valeurs d'objets ou tableaux dans des variables distinctes. Supporte les valeurs par defaut, 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 reponse API, les arguments de fonction.
import() en tant qu'expression retourne une Promise du module. Permet le chargement conditionnel et le code splitting a l'execution, contrairement aux imports statiques.
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 loadChart = async () => {
const { Chart } = await import('./chart.js');
return new Chart(data);
};
// Conditionnel
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 creer des erreurs custom via extends Error.
Differents codes d'alerte dans un hopital : chaque type indique immediatement la nature du probleme.
class AppError extends Error {
constructor(message, code) {
super(message);
this.name = 'AppError';
this.code = code;
}
}
throw new AppError('Not found', 404);Cas d'usage : Creer des erreurs metier typees pour un meilleur handling et des messages clairs.
Deux phases de propagation des evenements DOM. Capturing descend du document vers la cible, bubbling remonte de la cible vers le document. Par defaut, les listeners ecoutent 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 deleguer apres (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 recoit tous les appels de l'immeuble et les redirige 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, elements ajoutes apres le chargement.
Pattern publish/subscribe ou un emetteur envoie des evenements nommes et des listeners s'y abonnent. Base de EventTarget (DOM) et EventEmitter (Node.js).
Une radio : l'emetteur diffuse sur une frequence (evenement) et tous les recepteurs branches sur cette frequence 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 decouple entre composants, bus d'evenements, architecture event-driven.
Mecanisme central qui gere l'execution 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'execution du code asynchrone et debugger les problemes de timing.
Environnement abstrait dans lequel le code JS est evalue. Contient le Variable Environment, le Lexical Environment et la valeur de this. Cree pour chaque appel de fonction et le scope global.
La fiche d'identite d'un appel de fonction : qui elle est (this), ce qu'elle connait (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.
Proposition TC39 Stage 3+ avec le mot-cle using qui appelle automatiquement [Symbol.dispose]() a la sortie du scope. Equivalent du try-with-resources de Java ou using de C#.
Un robinet auto-coupant : il se ferme tout seul quand tu quittes la piece, pas besoin de penser a le fermer.
class FileHandle {
[Symbol.dispose]() {
console.log('File closed');
}
}
{
using file = new FileHandle();
// utiliser file...
} // [Symbol.dispose]() appele automatiquementCas d'usage : Gestion de connexions DB, handles fichier, locks, tout ce qui necessite un cleanup garanti.
API moderne de requetes HTTP basee sur les Promises, remplacant XMLHttpRequest. Retourne une Response avec des methodes pour parser le body (json, text, blob, etc.).
Un service de livraison moderne : tu passes commande (fetch), tu recois 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, telechargement de ressources.
API qui permet d'enregistrer un callback de nettoyage appele quand un objet observe est garbage-collecte. Companion de WeakRef pour le cleanup de ressources.
Un notaire qui execute 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 : Liberation 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 cles enumerables d'un objet, y compris la prototype chain.
for...of = lire chaque page d'un livre. for...in = lire la table des matieres (et potentiellement celles des annexes heritees).
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 proprietes d'objets (avec hasOwnProperty).
Processus automatique de liberation de la memoire non referencee. V8 utilise un GC generationnel : minor GC (young generation) frequent et major GC (old generation) moins souvent.
Un service de nettoyage qui ramasse les objets abandonnes dans un parc : si personne ne les reclame, ils sont jetes.
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 memoire, optimiser l'allocation, choisir entre Map/WeakMap.
Fonction speciale (function*) qui peut se suspendre via yield et reprendre. Retourne un iterateur. Permet la generation paresseuse de sequences potentiellement infinies.
Un livre dont tu tournes les pages une par une (yield) : l'histoire ne se deroule 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 : Sequences paresseuses, pagination, flux de donnees, implementation de iterables custom.
Mecanisme par lequel les declarations de variables (var) et fonctions sont remontees 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 debut 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'execution.
Immediately Invoked Function Expression : fonction anonyme executee immediatement a sa declaration. Cree un scope isole pour eviter la pollution globale. Moins utile depuis les modules ESM.
Un feu d'artifice a usage unique : tu l'allumes et il s'execute immediatement, 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 immediate, eviter les collisions globales.
Principe de ne jamais modifier les donnees existantes mais de creer 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 edition 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, detection de changements performante.
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 reelles (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 memoire d'une propriete apres le premier acces. Monomorphique (1 type) = rapide, polymorphique (2-4) = OK, megamorphique (5+) = lent.
Se souvenir exactement ou tu as range tes cles (toujours la meme 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 coherentes dans les hot paths pour maximiser les performances V8.
API qui observe de maniere asynchrone la visibilite d'un element par rapport a un ancetre ou au viewport. Remplace les calculs manuels de getBoundingClientRect dans un scroll listener.
Un vigile qui te previent 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, infinite scroll, animations au scroll, tracking d'impressions.
Convention definissant comment un objet produit une sequence de valeurs. Un objet est iterable s'il a une methode [Symbol.iterator]() retournant un iterateur avec next() -> {value, done}.
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 custom utilisables dans for...of, spread, et destructuring.
Compilation Just-In-Time : V8 interprete d'abord le bytecode (Ignition), puis compile en code machine optimise (TurboFan) les fonctions chaudes. Peut desoptimiser si les hypotheses sont invalides.
Un cuisinier qui improvise la premiere fois (interpretation), puis ecrit la recette (compilation) quand il a assez d'experience 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 malgre le typage dynamique, et comment eviter les deoptimisations.
Le scope d'une variable est determine par l'endroit ou elle est ecrite dans le code source, pas par l'endroit ou la fonction est appelee. C'est la base des closures en JS.
Ton adresse postale depend d'ou tu habites, pas d'ou tu te trouves quand tu recois 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 : Predire le comportement des closures et comprendre pourquoi JS n'utilise pas le dynamic scoping.
Operateurs &&=, ||= et ??= qui combinent affectation et logique. a ??= b assigne b a a seulement si a est null/undefined. Court-circuitage preserve.
Remplir un formulaire pre-rempli : tu n'ecris que dans les cases vides (??=), pas celles deja 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 defaut de maniere concise.
Collection cle-valeur ordonnee ou les cles peuvent etre de n'importe quel type (objets, fonctions, primitives). Plus performante qu'un objet pour les ajouts/suppressions frequents.
Un casier de vestiaire ou chaque casier a une cle unique de n'importe quelle forme, pas juste une etiquette 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 memoire, compteurs de frequences, lookup tables avec des cles non-string.
Algorithme de GC utilise par V8 : phase Mark parcourt le graphe d'objets depuis les racines (global, stack) et marque les atteignables. Phase Sweep libere les non-marques.
Un inventaire d'entrepot : 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 memoire.
Technique de cache qui stocke le resultat d'un appel de fonction base sur ses arguments. Si les memes arguments sont repasses, le resultat est retourne du cache sans recalcul.
Un carnet de notes : avant de recalculer, tu verifies si tu as deja note la reponse.
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 couteux appelees frequemment avec les memes parametres (fibonacci, selectors Redux).
Patterns courants de fuites memoire : event listeners non retires, closures retenant de gros objets, references DOM detachees, 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. Videe entierement 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 : Executer du code juste apres l'operation courante mais avant le prochain rendu ou timer.
API qui observe les changements du DOM (attributs, enfants, texte) de maniere asynchrone et performante. Remplace les deprecated Mutation Events.
Une camera de surveillance qui enregistre chaque modification dans une piece 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 : Detecter des modifications DOM par des scripts tiers, synchroniser un etat externe avec le DOM.
Operateur qui cree une instance : 1) cree un objet vide, 2) lie son [[Prototype]] au .prototype du constructeur, 3) execute le constructeur avec this = nouvel objet, 4) retourne l'objet.
Un moule a gateau : new prend le moule (constructeur), verse la pate (proprietes), et te donne un gateau (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.
Operateur ?? 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 securite qui ne se declenche que si le trapeziste 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 : Definir des valeurs par defaut en preservant les valeurs falsy legitimes comme 0, '' ou false.
Methodes statiques cles : Object.keys/values/entries (enumeration), 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 precis.
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 proprietes d'un objet de maniere standard.
Depuis ES2019, le parametre du catch est optionnel. Utile quand l'erreur n'est pas necessaire dans le traitement.
Savoir qu'il y a eu un probleme sans avoir besoin de lire le rapport detaille.
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.
Operateur ?. qui court-circuite a undefined si la valeur a gauche est null/undefined. Fonctionne sur les proprietes, methodes et acces dynamiques.
Frapper a une porte : si personne ne repond (?.), tu passes ton chemin au lieu de defoncer la porte (TypeError).
const city = user?.address?.city;
const result = obj?.method?.();
const val = arr?.[0]?.name;Cas d'usage : Acceder a des proprietes de donnees API incertaines sans multiplier les verifications if.
Fixer un ou plusieurs arguments d'une fonction pour creer une nouvelle fonction avec moins de parametres. 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 : Creer des variantes de fonctions utilitaires (logger avec prefix, requetes avec base URL).
API qui observe les entrees de la Performance Timeline (paint, navigation, resource, longtask, etc.). Permet de collecter les metriques Web Vitals de maniere non-bloquante.
Un chronometre automatique qui enregistre les temps de chaque etape d'une course sans que les coureurs s'arretent.
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 prefixes par # veritablement prives (hard private). Non accessibles en dehors de la classe, meme par les sous-classes. Contrairement aux conventions _prefix.
Un coffre-fort dans ta chambre : meme 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 representant le resultat futur d'une operation asynchrone. Peut etre pending, fulfilled ou rejected. Chainable via .then() et .catch().
Un ticket de pressing : tu deposes ton vetement, tu recois un ticket, et tu reviens le chercher quand c'est pret (ou on te previent 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 : Gerer toute operation asynchrone : appels API, lecture de fichiers, timers.
Les rejections de Promise doivent etre catchees avec .catch() ou try/catch avec await. Les rejections non gerees declenchent unhandledrejection et peuvent crasher en Node.js.
Un filet sous le trapeze : 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 chaine de promesses doit avoir un catch terminal pour eviter les rejections silencieuses.
Combinateurs de promesses : all (toutes reussies ou 1 echec), allSettled (toutes terminees), race (la premiere terminee), any (la premiere reussie). Essentiels pour le parallelisme.
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 repondu, oui ou non.
const [a, b] = await Promise.all([fetchA(), fetchB()]);
const results = await Promise.allSettled([p1, p2]);
const fastest = await Promise.race([p1, p2]);
const first = await Promise.any([p1, p2]);Cas d'usage : Paralleliser des appels API independants (all), tolerant aux echecs (allSettled), timeout (race).
Modele d'heritage de JS ou les objets heritent directement d'autres objets via la prototype chain, contrairement a l'heritage 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 referer 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 : Creer des hierarchies d'objets legeres sans le cout d'un systeme de classes complet.
Chaine de prototypes par laquelle JS recherche les proprietes et methodes. Chaque objet a un [[Prototype]] interne qui pointe vers un autre objet, jusqu'a null.
L'arbre genealogique : si tu ne sais pas cuisiner, tu demandes a ta mere, puis a ta grand-mere, en remontant les generations.
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'heritage en JS, le fonctionnement de class/extends, et optimiser la recherche de proprietes.
Objet qui encapsule un autre objet et intercepte les operations fondamentales (get, set, has, delete, etc.) via des traps. Base de la reactivite dans Vue 3 et des ORMs modernes.
Un secretaire 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 : Systemes reactifs (Vue 3), validation automatique, logging transparent, mocking en tests.
Fonction qui retourne toujours le meme resultat pour les memes arguments et ne produit aucun effet de bord. Deterministe et sans mutation d'etat 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 leger que Promise.resolve().then() pour planifier une microtask.
Glisser un post-it urgent sur la pile 'a traiter immediatement' au lieu de creer un ticket formel (Promise).
console.log('1');
queueMicrotask(() => console.log('2'));
console.log('3');
// 1, 3, 2Cas d'usage : Differer une action apres le code synchrone courant mais avant le prochain rendu.
Objet built-in fournissant des methodes statiques pour les operations interceptables par Proxy. Miroir 1:1 des traps de Proxy avec des retours booleens au lieu d'exceptions.
Le mode d'emploi officiel des operations JS : au lieu de bidouiller, tu utilises la methode 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 defaut correct.
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 metronome 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 periodes d'inactivite du navigateur. Recoit un IdleDeadline indiquant le temps restant. Ideal pour les taches non-urgentes.
Faire le menage pendant les pubs a la tele : 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.
API qui observe les changements de taille d'un element DOM. Appelle le callback quand les dimensions changent, sans dependre du resize de la fenetre.
Un metre 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.
Chaine de references entre les scopes imbriques qui permet a une fonction d'acceder aux variables de ses scopes parents. La recherche remonte la chaine jusqu'au scope global.
Chercher un livre dans ta chambre, puis le salon, puis la bibliotheque 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 resolution des variables et eviter les collisions de noms entre scopes imbriques.
Proxy programmable entre l'app et le reseau, tournant en arriere-plan. Intercepte les requetes fetch pour implementer du cache offline, des push notifications et la synchronisation en arriere-plan.
Un concierge d'hotel qui intercepte ton courrier : il peut te le remettre du stock (cache) sans appeler le facteur (reseau).
// 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 de n'importe quel type. L'ajout d'un doublon est silencieusement ignore. Iterable et ordonnee par ordre d'insertion.
Un tampon encreur qui marque les invites a l'entree : meme si tu te representes, tu n'es compte qu'une fois.
const unique = new Set([1, 2, 2, 3]);
unique.size; // 3
unique.add(4);
unique.has(2); // true
// Deduplication rapide
[...new Set(array)];Cas d'usage : Deduplication de tableaux, tracking d'elements uniques, verification d'appartenance O(1).
Toute modification d'etat observable en dehors de la fonction : mutation de variable globale, ecriture DOM, appel reseau, 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 : Necessaires en pratique (I/O, DOM, API), mais a isoler et controler dans des couches dediees.
Code execute 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 piege : juste en l'ouvrant (import), quelque chose se declenche 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 : Declarer correctement sideEffects pour permettre un tree shaking optimal par le bundler.
L'operateur ... sert de spread (etaler un iterable) ou rest (collecter les arguments restants). Spread copie superficiellement, rest regroupe dans un tableau.
Spread = etaler 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 maniere immutable, collecter des arguments variadiques.
stopPropagation empeche l'evenement de remonter/descendre aux parents mais execute les autres listeners du meme element. stopImmediatePropagation arrete aussi les listeners suivants sur le meme element.
stopPropagation = fermer la porte de ta chambre (les voisins n'entendent plus). stopImmediate = aussi couper le son dans ta chambre (meme 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 : Empecher un modal de se fermer quand on clique a l'interieur, isoler des composants.
API pour traiter des donnees en flux (ReadableStream, WritableStream, TransformStream). Permet de consommer des donnees chunk par chunk sans tout charger en memoire.
Un tuyau d'arrosage : l'eau (donnees) coule en continu au lieu d'etre livree en citerne entiere.
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 : Telecharger des gros fichiers avec progression, streaming SSE/LLM, traitement video/audio.
Mode d'execution plus strict active par 'use strict' ou implicitement dans les modules ESM. Interdit les variables non declarees, 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 signalee immediatement.
'use strict';
x = 5; // ReferenceError
delete Object.prototype; // TypeError
function f() { return this; } // undefinedCas d'usage : Actif par defaut dans les modules ESM et les classes. Attrape les erreurs silencieuses tot.
API globale structuredClone() qui cree une copie profonde d'un objet, supportant les types complexes (Date, Map, Set, ArrayBuffer, etc.). Remplace JSON.parse(JSON.stringify()).
Une photocopieuse couleur haute fidelite qui reproduit chaque detail, 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'etats complexes, transfert de donnees entre workers, copie d'objets avec types speciaux.
JSON.parse(JSON.stringify()) perd les Date, Map, Set, undefined, fonctions et references circulaires. structuredClone gere tout sauf les fonctions et le DOM. Toujours preferer structuredClone.
JSON = scanner un document en noir et blanc (perd les couleurs). structuredClone = photocopier en couleur haute fidelite.
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'etats complexes avec des types non-JSON.
Type primitif unique et immutable cree par Symbol(). Utilise comme cle de propriete pour eviter les collisions. Les well-known symbols (Symbol.iterator, etc.) customisent le comportement du langage.
Un numero de serie unique grave sur une cle : meme si deux cles se ressemblent, leurs numeros sont differents.
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 : Creer des proprietes privees-like, definir des protocoles (iterator), eviter les collisions de noms en libs.
Fonction appelee avec un template literal comme argument. Recoit les parties statiques et les valeurs interpolees separement, permettant un traitement personnalise.
Un traducteur qui recoit la phrase avec des trous et les mots a inserer, 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 securise, 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 etiquette de couleur : bleu = fragile, rouge = urgent. L'etiquette determine 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 generique 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 corvees a faire une par une : apres chaque corvee, tu verifies 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 : Decomposer un traitement lourd en petits morceaux via setTimeout pour ne pas bloquer le thread principal.
Chaines delimitees 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 insere les valeurs.
const name = 'World';
const greeting = `Hello, ${name}!`;
const multiline = `
Line 1
Line 2
`;Cas d'usage : Construire des chaines dynamiques, des requetes SQL parametrees (via tagged templates), du HTML.
Zone entre le debut du scope et la declaration let/const ou la variable existe mais est inaccessible. Toute tentative d'acces lance un ReferenceError.
Un colis en transit : il a ete expedie (hoiste) mais tu ne peux pas l'ouvrir tant qu'il n'est pas livre (declaration).
{
// 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.
Reference au contexte d'execution courant. Sa valeur depend de comment la fonction est appelee : methode (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 ecrite.
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 : Acceder aux proprietes de l'objet courant dans les methodes de classe ou les callbacks.
Limite l'execution d'une fonction a maximum une fois par intervalle de temps. Contrairement au debounce, garantit une execution reguliere pendant une rafale d'appels.
Un robinet a debit controle : meme si tu l'ouvres a fond, l'eau coule toujours a la meme 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 resolution.
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 demarrage d'un module ESM.
Transformations composables et independantes du type de collection. Combine map, filter, reduce en un seul passage sans creer de tableaux intermediaires.
Un ouvrier polyvalent sur une chaine de montage qui fait tri + transformation + emballage en un seul passage au lieu de trois passages separes.
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 donnees en un seul passage, eviter les allocations intermediaires.
Elimination du code mort par les bundlers (Webpack, Rollup, esbuild) basee sur l'analyse statique des imports ESM. Seuls les exports effectivement importes sont inclus dans le bundle final.
Secouer un arbre pour ne garder que les fruits murs (code utilise) et laisser tomber les feuilles mortes (code inutilise).
// utils.js
export const used = () => 'kept';
export const unused = () => 'removed';
// app.js
import { used } from './utils';
// unused est elimine du bundleCas d'usage : Reduire la taille des bundles en production, surtout avec de grosses librairies comme lodash.
Map dont les cles sont obligatoirement des objets et sont tenues faiblement : si plus aucune reference forte n'existe vers la cle, l'entree est garbage-collectee. Non iterable.
Des post-it colles sur des objets : quand l'objet part a la poubelle, le post-it disparait 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 privees sur des objets sans empecher leur garbage collection.
Reference faible vers un objet qui n'empeche pas sa garbage collection. Acces via .deref() qui retourne l'objet ou undefined s'il a ete GC.
Prendre une photo d'un objet au lieu de le garder : tu peux regarder la photo, mais l'objet peut avoir ete jete 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 legers, references 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 empecher 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 : Detecter les references circulaires, marquer les noeuds DOM deja traites.
API de communication bidirectionnelle persistante entre client et serveur via le protocole ws://. Permet l'envoi et la reception de messages en temps reel sans polling.
Un telephone : 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 reel, notifications live, trading, jeux multijoueur, dashboards temps reel.
API permettant d'executer du JS dans un thread separe du thread principal. Communiquent via postMessage/onmessage. N'ont pas acces au DOM.
Un assistant dans un bureau separe : tu lui envoies du travail par pneumatique (postMessage), il te renvoie le resultat.
// 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, operations qui bloqueraient le thread UI.
Autres stacks