Skip to Content
SnippetsJavaScript / TypeScript

JavaScript / TypeScript

Fonctions utilitaires, patterns de manipulation de données et outils TypeScript pour le quotidien.

⚡ Utilitaires courants

Debounce

Retarde l’exécution d’une fonction jusqu’après un temps d’inactivité.

function debounce(fn, ms = 300) { let timer; return (...args) => { clearTimeout(timer); timer = setTimeout(() => fn(...args), ms); }; } // Usage : rechercher après 300 ms d'inactivité const recherche = debounce((query) => { fetch(`/api/search?q=${query}`).then(renderResults); }, 300); input.addEventListener('input', (e) => recherche(e.target.value));

Throttle

Exécute une fonction au maximum une fois toutes les ms millisecondes.

function throttle(fn, ms = 300) { let last = 0; return (...args) => { const now = Date.now(); if (now - last >= ms) { last = now; fn(...args); } }; } // Usage : limiter le scroll handler window.addEventListener('scroll', throttle(() => { updateScrollIndicator(); }, 100));

Unique par clé

Crée un tableau sans doublons — natif avec Set, ou avec Map pour préserver l’ordre et les objets complexes.

// Basique (ordre non garanti) [...new Set([3, 1, 2, 1, 3, 2])]; // [3, 1, 2] // Ordre préservé + clé custom (ex: objets par id) function uniqueBy(arr, keyFn) { const seen = new Map(); return arr.filter(item => { const key = keyFn(item); if (seen.has(key)) return false; seen.set(key, true); return true; }); } const users = [ { id: 1, nom: 'Alice' }, { id: 2, nom: 'Bob' }, { id: 1, nom: 'Alice Duplicate' }, ]; uniqueBy(users, u => u.id); // [{ id: 1, nom: 'Alice' }, { id: 2, nom: 'Bob' }]

GroupBy

Regroupe les éléments d’un tableau par une clé calculée.

function groupBy(arr, keyFn) { return arr.reduce((groups, item) => { const key = keyFn(item); (groups[key] = groups[key] || []).push(item); return groups; }, {}); } const people = [ { nom: 'Alice', role: 'dev' }, { nom: 'Bob', role: 'dev' }, { nom: 'Carol', role: 'design' }, ]; groupBy(people, p => p.role); // { // dev: [{ nom: 'Alice', role: 'dev' }, { nom: 'Bob', role: 'dev' }], // design: [{ nom: 'Carol', role: 'design' }] // }

Chunk

Découpe un tableau en blocs de taille size.

function chunk(arr, size) { return Array.from({ length: Math.ceil(arr.length / size) }, (_, i) => arr.slice(i * size, i * size + size) ); } chunk([1, 2, 3, 4, 5, 6, 7], 3); // [[1, 2, 3], [4, 5, 6], [7]]

Pitfall : chunk avec size = 0 renvoie Infinity dans Math.ceil() → array infini. Guard : if (size <= 0) return [];

📊 Tableaux

Map / Filter / Reduce — chaînage

// Extraire les noms des utilisateurs actifs, triés par longueur const noms = users .filter(u => u.actif) .map(u => u.nom) .sort((a, b) => a.length - b.length); // Aggregate : somme des montants par catégorie const totals = transactions .reduce((acc, t) => { acc[t.categorie] = (acc[t.categorie] || 0) + t.montant; return acc; }, {});

Immutabilité

Toujours créer de nouveaux tableaux, jamais modifier l’original.

// ❌ Ne jamais faire : arr.push(item); // mutatif arr[0] = newValue; // mutatif arr.sort(); // mutatif (.sort modifie en place !) // ✅ Toujours faire : const newArr = [...arr, item]; const replaced = arr.map((v, i) => i === idx ? newValue : v); const sorted = [...arr].sort((a, b) => a - b);

Array.from & flatMap

// Créer un tableau à partir d'un objet itérable Array.from({ length: 5 }, (_, i) => i + 1); // [1, 2, 3, 4, 5] // flatMap : map + flatten à un niveau (indispensable) const mots = ['hello world', 'foo bar']; mots.flatMap(m => m.split(' ')); // ['hello', 'world', 'foo', 'bar'] // Équivalent manuel (plus verbeux) : mots.map(m => m.split(' ')).flat();

🧩 Objets & destructuring

Destructuring avancé

// Valeurs par défaut const { host = 'localhost', port = 3000 } = config; // Renommer à la volée const { id: userId, nom: userName } = user; // Destructuring imbriqué const { data: { users: userList, meta: { page } } } = response; // Spread pour capturer le reste des propriétés const { password, ...sansMdp } = user; // sansMdp = { id: 1, nom: 'Alice' } // Déstructuring avec guard (objet potentiellement undefined) const items = parsed.data?.items ?? []; items.forEach(({ nom, prix }) => console.log(nom, prix));

Pitfall : déstructurer un objet null ou undefined lève TypeError. Toujours utiliser un fallback : const { x } = obj ?? {};

Object.entries / keys / values

const config = { debug: true, port: 3000, host: 'localhost' }; // Clés Object.keys(config); // ['debug', 'port', 'host'] // Valeurs Object.values(config); // [true, 3000, 'localhost'] // Paires [key, value] — utile pour les boucles filtrées Object.entries(config) .filter(([, v]) => typeof v === 'string') .map(([k, v]) => `${k.toUpperCase()}=${v}`); // ['HOST=localhost']

Spread & copy profonde limitée

// Shallow copy : une seule couche const clone = { ...original }; // Deep clone limité (JSON) — perd Date, RegExp, undefined, Map, Set const deep = JSON.parse(JSON.stringify(obj)); // Deep clone robuste (navigateurs modernes) const safe = structuredClone(obj); // préserve : Date, RegExp, Map, Set, ArrayBuffer, etc.