Combine les fonctionnalités JavaScript modernes en patterns pratiques — affectation court-circuit, astuces d'objets, mises à jour immutables, et plus encore.
Les opérateurs logiques de JavaScript peuvent être utilisés pour des patterns conditionnels concis au-delà de la simple logique booléenne.
Valeurs par défaut avec || :
const name = userInput || 'Anonymous';
// Retourne userInput s'il est truthy, sinon 'Anonymous'Défaut nullish avec ?? :
const count = data.count ?? 0;
// Ne revient à 0 que si count est null/undefined
// Préserve 0, '', false (contrairement à ||)Garde avec && :
isLoggedIn && showDashboard();
// N'appelle showDashboard() que si isLoggedIn est truthy
const name = user && user.name;
// Retourne user.name si user est truthy, sinon user (null/undefined)Opérateurs d'affectation logique (ES2021) :
let config = {};
config.theme ??= 'light'; // affecte si null/undefined
config.debug ||= false; // affecte si falsy
config.retries &&= config.retries - 1; // affecte si truthyConversion en booléen :
const hasItems = !!items.length; // 0 → false, 5 → true
const isValid = !!input.trim(); // '' → false, 'hello' → trueJavaScript moderne fournit des raccourcis élégants pour travailler avec des objets.
Propriétés raccourcies — quand le nom de variable correspond à la clé :
const name = 'Alice';
const age = 30;
// Au lieu de { name: name, age: age }
const user = { name, age };Noms de propriétés calculés :
const field = 'email';
const obj = { [field]: 'alice@example.com' };
console.log(obj.email); // 'alice@example.com'
// Clés dynamiques
const prefix = 'user';
const data = {
[`${prefix}Name`]: 'Alice',
[`${prefix}Age`]: 30,
};Object.assign() vs spread :
// Les deux fusionnent des objets (spread est préféré)
const merged1 = Object.assign({}, defaults, overrides);
const merged2 = { ...defaults, ...overrides };Object.freeze() — empêche les modifications :
const config = Object.freeze({ port: 3000, host: 'localhost' });
config.port = 8080; // échoue silencieusement (lance une erreur en mode strict)Object.keys/values/entries :
const user = { name: 'Alice', age: 30 };
Object.keys(user); // ['name', 'age']
Object.values(user); // ['Alice', 30]
Object.entries(user); // [['name', 'Alice'], ['age', 30]]En JavaScript moderne — surtout avec React et Redux — tu ne dois jamais muter le state directement. À la place, crée de nouvelles copies avec les changements appliqués.
Mise à jour d'objets :
const user = { name: 'Alice', age: 25, city: 'Paris' };
// Crée un nouvel objet avec l'age mis à jour
const updated = { ...user, age: 26 };
console.log(user.age); // 25 (original inchangé)
console.log(updated.age); // 26Ajout d'éléments aux tableaux :
const items = ['apple', 'banana'];
const added = [...items, 'cherry'];
// ['apple', 'banana', 'cherry']
const prepended = ['mango', ...items];
// ['mango', 'apple', 'banana']Suppression d'éléments des tableaux :
const numbers = [1, 2, 3, 4, 5];
const without3 = numbers.filter(n => n !== 3);
// [1, 2, 4, 5]Mise à jour d'éléments dans les tableaux :
const todos = [
{ id: 1, text: 'Buy milk', done: false },
{ id: 2, text: 'Clean house', done: false },
];
const toggled = todos.map(todo =>
todo.id === 1 ? { ...todo, done: true } : todo
);Mise à jour d'objets imbriqués :
const state = { user: { name: 'Alice', address: { city: 'Paris' } } };
const newState = {
...state,
user: {
...state.user,
address: {
...state.user.address,
city: 'London',
},
},
};Les concepts de programmation fonctionnelle sont largement utilisés en JavaScript moderne.
Fonctions pures — sans effets de bord, la même entrée donne toujours la même sortie :
// Pure
const add = (a, b) => a + b;
const toUpper = str => str.toUpperCase();
// Impure (modifie l'état externe)
let count = 0;
const increment = () => ++count;Fonctions d'ordre supérieur — fonctions qui acceptent ou retournent des fonctions :
// Accepte une fonction
const numbers = [1, 2, 3];
const doubled = numbers.map(n => n * 2);
// Retourne une fonction
const multiplier = factor => number => number * factor;
const double = multiplier(2);
const triple = multiplier(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15Composition — combiner des fonctions :
const pipe = (...fns) => value =>
fns.reduce((acc, fn) => fn(acc), value);
const processName = pipe(
str => str.trim(),
str => str.toLowerCase(),
str => str.replace(/\s+/g, '-')
);
console.log(processName(' Hello World ')); // 'hello-world'IIFE (Immediately Invoked Function Expression) — pour une initialisation unique :
const config = (() => {
const env = 'production';
return { env, debug: env !== 'production' };
})();Les versions récentes de JavaScript ont ajouté plusieurs fonctionnalités de confort.
Séparateurs numériques pour la lisibilité :
const billion = 1_000_000_000;
const bytes = 0xFF_FF_FF;
const fraction = 0.000_001;globalThis — objet global universel :
// Fonctionne dans les navigateurs, Node.js, web workers, etc.
globalThis.myGlobal = 'hello';structuredClone() — copie profonde appropriée :
const original = { a: 1, nested: { b: 2 } };
const deep = structuredClone(original);
deep.nested.b = 99;
console.log(original.nested.b); // 2 (non affecté !)Array.at() — accès depuis la fin :
const arr = ['a', 'b', 'c', 'd'];
console.log(arr.at(-1)); // 'd' (dernier élément)
console.log(arr.at(-2)); // 'c' (avant-dernier)Object.hasOwn() — plus sûr que hasOwnProperty :
const obj = { name: 'Alice' };
console.log(Object.hasOwn(obj, 'name')); // true
console.log(Object.hasOwn(obj, 'toString')); // falseString replaceAll() :
const text = 'foo-bar-baz';
console.log(text.replaceAll('-', '_')); // 'foo_bar_baz'<div id="output"></div>
<script>
// Immutable update
const user = { name: 'Alice', age: 25, city: 'Paris' };
const updated = { ...user, age: 26 };
// Short-circuit default
const displayName = user.nickname ?? user.name;
// Shorthand properties
const x = 10, y = 20;
const point = { x, y };
// Deep clone with structuredClone
const original = { data: { items: [1, 2, 3] } };
const cloned = structuredClone(original);
cloned.data.items.push(4);
// Array.at() for last element
const colors = ['red', 'green', 'blue'];
const lastColor = colors.at(-1);
const output = document.getElementById('output');
output.innerHTML = `
<p>Original age: ${user.age}, Updated age: ${updated.age}</p>
<p>Display name: ${displayName}</p>
<p>Point: {x: ${point.x}, y: ${point.y}}</p>
<p>Original items: [${original.data.items}] (not mutated)</p>
<p>Cloned items: [${cloned.data.items}]</p>
<p>Last color: ${lastColor}</p>
`;
</script>Que fait `{ ...user, age: 30 }` ?