JavaScript ES2024 : Syntaxe moderne
Variables et constantes
Déclarations
// const - immuable (référence)
const nom = 'Jean';
const age = 30;
// nom = 'Marie'; // Erreur
const user = { nom: 'Jean' };
user.nom = 'Marie'; // OK - objet mutable
// user = {}; // Erreur - référence immuable
// let - variable locale au bloc
let compteur = 0;
compteur = 1; // OK
if (true) {
let local = 'bloc';
}
// console.log(local); // Erreur - hors scope
// var - éviter (scope fonction, hoisting)
var ancien = 'à éviter';
// Bonnes pratiques:
// 1. Toujours const par défaut
// 2. let si réassignation nécessaire
// 3. Jamais var
Destructuration
// Arrays
const [a, b] = [1, 2];
const [first, ...rest] = [1, 2, 3, 4]; // first=1, rest=[2,3,4]
const [x, , z] = [1, 2, 3]; // x=1, z=3 (skip 2)
const [val = 0] = []; // Valeur par défaut
// Objects
const { nom, age } = { nom: 'Jean', age: 30 };
const { nom: username, age: userAge } = user; // Renommer
const { nom = 'Anonyme' } = {}; // Valeur par défaut
const { address: { city } } = user; // Nested
// Paramètres fonction
function saluer({ nom, age = 18 }) {
return ${nom} (${age} ans);
}
// Rest dans objets
const { id, ...userData } = user;
// Swap variables
[a, b] = [b, a];
Types de données
Types primitifs
// String
const str = 'simple quote';
const str2 = "double quote";
const template = Template literal avec ${variable};
const multiline = `
Multiligne
automatique
`;
// Number
const int = 42;
const float = 3.14;
const exp = 2.5e3; // 2500
const hex = 0xFF; // 255
const octal = 0o777; // 511
const binary = 0b1010; // 10
const big = 1000000; // Séparateurs (1000000)
// BigInt (nombres arbitrairement grands)
const bigInt = 9007199254740991n;
const big2 = BigInt(9007199254740991);
// Boolean
const vrai = true;
const faux = false;
// Null et Undefined
const nul = null; // Absence intentionnelle
let indefini; // undefined - non initialisé
// Symbol (identifiant unique)
const sym = Symbol('description');
const sym2 = Symbol('description');
console.log(sym === sym2); // false
Vérification de types
// typeof
typeof 'string'; // 'string'
typeof 42; // 'number'
typeof true; // 'boolean'
typeof undefined; // 'undefined'
typeof null; // 'object' (bug historique)
typeof {}; // 'object'
typeof []; // 'object'
typeof function() {}; // 'function'
// instanceof
[] instanceof Array; // true
{} instanceof Object; // true
// Array
Array.isArray([]); // true
Array.isArray({}); // false
// Nombre
Number.isNaN(NaN); // true
Number.isFinite(42); // true
Number.isInteger(42); // true
// Null et undefined
value === null;
value === undefined;
value == null; // null OU undefined
// Truthy / Falsy
// Falsy: false, 0, '', null, undefined, NaN
// Truthy: tout le reste
if (value) { / truthy / }
// Nullish coalescing (ES2020)
const result = value ?? 'default'; // default si null ou undefined
const result2 = value || 'default'; // default si falsy
Opérateurs modernes
Opérateurs logiques
// Nullish coalescing (??)
const user = null;
const name = user ?? 'Anonyme'; // 'Anonyme'
const name2 = user || 'Anonyme'; // Même résultat ici
const count = 0;
const value1 = count ?? 10; // 0 (car count n'est pas nullish)
const value2 = count || 10; // 10 (car 0 est falsy)
// Optional chaining (?.)
const city = user?.address?.city; // undefined si user ou address null/undefined
const fn = obj.method?.(); // Appel conditionnel
const item = arr?.[0]; // Accès array conditionnel
// Logical assignment (ES2021)
x ??= 5; // x = x ?? 5
x ||= 5; // x = x || 5
x &&= 5; // x = x && 5
// Exemples pratiques
let config = null;
config ??= getDefaultConfig(); // Assigne seulement si nullish
user.profile ||= createProfile(); // Assigne si falsy
user.valid &&= checkUser(user); // Assigne si truthy
Opérateurs avancés
// Spread operator (...)
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]
const copy = [...arr1]; // Copie shallow
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }
const merge = { ...obj1, ...obj2 };
// Spread dans fonctions
function sum(...numbers) {
return numbers.reduce((a, b) => a + b, 0);
}
sum(1, 2, 3, 4); // 10
Math.max(...[1, 5, 3]); // 5
// Exponentiation ()
2 3; // 8
Math.pow(2, 3); // 8 (ancienne méthode)
// Exponential assignment
let x = 2;
x = 3; // x = x 3 = 8
Fonctions
Fonctions fléchées
// Syntaxe basique
const add = (a, b) => a + b;
const square = x => x x; // 1 param: parenthèses optionnelles
const log = () => console.log('test'); // 0 param: parenthèses requises
// Bloc de code
const complex = (a, b) => {
const result = a + b;
return result 2;
};
// Retour objet (parenthèses requises)
const makeUser = (nom, age) => ({ nom, age });
// Pas de this propre (hérite du contexte)
const obj = {
value: 42,
regular: function() { return this.value; }, // this = obj
arrow: () => this.value // this = contexte parent
};
// Cas d'usage appropriés
[1, 2, 3].map(x => x 2);
setTimeout(() => console.log('delayed'), 1000);
promise.then(data => console.log(data));
// À éviter: méthodes d'objet, constructeurs
Paramètres
// Paramètres par défaut
function greet(name = 'Guest', age = 18) {
return Hello ${name}, ${age} years old;
}
// Paramètres rest
function sum(first, ...numbers) {
return numbers.reduce((acc, n) => acc + n, first);
}
sum(1, 2, 3, 4); // 10
// Destructuration paramètres
function drawCircle({ x = 0, y = 0, radius = 10 } = {}) {
console.log(Circle at (${x}, ${y}) with radius ${radius});
}
drawCircle({ x: 5, radius: 20 });
// Arguments variables avec spread
function multiply(multiplier, ...numbers) {
return numbers.map(n => n multiplier);
}
Fonctions asynchrones
// Async/Await
async function fetchData() {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
return data;
}
// Gestion erreurs
async function getData() {
try {
const data = await fetchData();
return data;
} catch (error) {
console.error('Error:', error);
throw error;
}
}
// Async arrow function
const fetchUser = async (id) => {
const response = await fetch(/api/users/${id});
return response.json();
};
// Await multiples
async function getAll() {
const [users, posts] = await Promise.all([
fetchUsers(),
fetchPosts()
]);
return { users, posts };
}
// Top-level await (modules ES)
const data = await fetchData();
// Async IIFE
(async () => {
const data = await fetchData();
console.log(data);
})();
Structures de données
Arrays (tableaux)
// Création
const arr = [1, 2, 3];
const arr2 = new Array(3); // [empty × 3]
const arr3 = Array.of(1, 2, 3); // [1, 2, 3]
const arr4 = Array.from('hello'); // ['h', 'e', 'l', 'l', 'o']
// Méthodes modernes
// map - transformer chaque élément
[1, 2, 3].map(x => x 2); // [2, 4, 6]
// filter - filtrer éléments
[1, 2, 3, 4].filter(x => x > 2); // [3, 4]
// reduce - réduire à une valeur
[1, 2, 3, 4].reduce((acc, x) => acc + x, 0); // 10
// find - trouver premier élément
[1, 2, 3].find(x => x > 1); // 2
// findIndex - index du premier élément
[1, 2, 3].findIndex(x => x > 1); // 1
// findLast / findLastIndex (ES2023)
[1, 2, 3, 2, 1].findLast(x => x === 2); // 2 (dernier)
[1, 2, 3, 2, 1].findLastIndex(x => x === 2); // 3
// some - au moins un élément valide
[1, 2, 3].some(x => x > 2); // true
// every - tous les éléments valides
[1, 2, 3].every(x => x > 0); // true
// includes - contient valeur
[1, 2, 3].includes(2); // true
// flat - aplatir tableau
[1, [2, [3, 4]]].flat(); // [1, 2, [3, 4]]
[1, [2, [3, 4]]].flat(2); // [1, 2, 3, 4]
[1, [2, [3, 4]]].flat(Infinity); // [1, 2, 3, 4]
// flatMap - map puis flat
[[1, 2], [3, 4]].flatMap(arr => arr.map(x => x 2)); // [2, 4, 6, 8]
// forEach - itérer (pas de return)
[1, 2, 3].forEach((x, i) => console.log(i, x));
// at - accès par index (négatif OK) (ES2022)
[1, 2, 3].at(0); // 1
[1, 2, 3].at(-1); // 3 (dernier)
// Modification
// push/pop - fin
arr.push(4); // Ajoute à la fin, retourne longueur
arr.pop(); // Retire fin, retourne élément
// unshift/shift - début
arr.unshift(0); // Ajoute au début
arr.shift(); // Retire début
// splice - modifier n'importe où
arr.splice(1, 2); // Retire 2 éléments à partir index 1
arr.splice(1, 0, 'a', 'b'); // Insère à index 1
arr.splice(1, 1, 'new'); // Remplace à index 1
// slice - extraire portion (non-mutant)
arr.slice(1, 3); // Éléments index 1 et 2
arr.slice(-2); // 2 derniers
// toSpliced / toReversed / toSorted (ES2023) - versions non-mutantes
const sorted = arr.toSorted((a, b) => a - b);
const reversed = arr.toReversed();
// concat - concaténer
[1, 2].concat([3, 4]); // [1, 2, 3, 4]
// join - convertir en string
[1, 2, 3].join('-'); // '1-2-3'
// Tri
arr.sort(); // Tri alphabétique
arr.sort((a, b) => a - b); // Tri numérique croissant
arr.sort((a, b) => b - a); // Tri décroissant
arr.reverse(); // Inverse ordre
// Utilitaires
arr.length; // Taille
arr.fill(0); // Remplit avec valeur
arr.fill(0, 2, 4); // Remplit index 2-3 avec 0
Objects (objets)
// Création
const obj = { nom: 'Jean', age: 30 };
const obj2 = new Object();
const obj3 = Object.create(null); // Sans prototype
// Propriétés
// Computed property names
const key = 'age';
const obj4 = { [key]: 30 }; // { age: 30 }
// Shorthand property
const nom = 'Jean';
const age = 30;
const user = { nom, age }; // { nom: 'Jean', age: 30 }
// Shorthand methods
const obj5 = {
greet() { return 'Hello'; }, // Au lieu de: greet: function() {}
async fetch() { return await getData(); }
};
// Getters/Setters
const person = {
firstName: 'Jean',
lastName: 'Dupont',
get fullName() {
return ${this.firstName} ${this.lastName};
},
set fullName(name) {
[this.firstName, this.lastName] = name.split(' ');
}
};
// Accès
obj.nom; // Dot notation
obj['nom']; // Bracket notation
obj?.nom; // Optional chaining
// Modification
obj.nom = 'Marie';
obj['age'] = 31;
delete obj.age;
// Méthodes Object
// Keys, values, entries
Object.keys(obj); // ['nom', 'age']
Object.values(obj); // ['Jean', 30]
Object.entries(obj); // [['nom', 'Jean'], ['age', 30]]
// fromEntries (inverse de entries)
Object.fromEntries([['nom', 'Jean'], ['age', 30]]); // { nom: 'Jean', age: 30 }
// assign - copier propriétés
Object.assign({}, obj); // Copie shallow
Object.assign(target, source1, source2); // Merge
// freeze - empêcher modifications
Object.freeze(obj);
// seal - empêcher ajout/suppression
Object.seal(obj);
// hasOwn (ES2022) - meilleur que hasOwnProperty
Object.hasOwn(obj, 'nom'); // true
// getOwnPropertyDescriptor
Object.getOwnPropertyDescriptor(obj, 'nom');
// defineProperty
Object.defineProperty(obj, 'readonly', {
value: 42,
writable: false,
enumerable: true,
configurable: false
});
// Prototype
Object.getPrototypeOf(obj);
Object.setPrototypeOf(obj, proto);
// Grouping (ES2024)
const items = [
{ type: 'fruit', name: 'apple' },
{ type: 'fruit', name: 'banana' },
{ type: 'vegetable', name: 'carrot' }
];
Object.groupBy(items, item => item.type);
// { fruit: [{...}, {...}], vegetable: [{...}] }
Set (ensemble)
// Création
const set = new Set([1, 2, 3]);
const set2 = new Set(); // Vide
// Ajout/Suppression
set.add(4);
set.add(4); // Pas de doublons
set.delete(2);
set.clear(); // Vide tout
// Vérification
set.has(1); // true
set.size; // Taille
// Itération
for (const value of set) {
console.log(value);
}
set.forEach(value => console.log(value));
// Conversion
[...set]; // Vers array
Array.from(set);
// Utilités
// Supprimer doublons d'array
const unique = [...new Set([1, 2, 2, 3])]; // [1, 2, 3]
// Opérations ensemblistes
const a = new Set([1, 2, 3]);
const b = new Set([2, 3, 4]);
// Union (ES2025 proposal)
const union = new Set([...a, ...b]); // [1, 2, 3, 4]
// Intersection
const intersection = new Set([...a].filter(x => b.has(x))); // [2, 3]
// Différence
const difference = new Set([...a].filter(x => !b.has(x))); // [1]
Map (dictionnaire)
// Création
const map = new Map([
['key1', 'value1'],
['key2', 'value2']
]);
// Clés de tout type (vs objet: string/symbol uniquement)
map.set(1, 'number key');
map.set({ id: 1 }, 'object key');
map.set(true, 'boolean key');
// Get/Set/Delete
map.get('key1'); // 'value1'
map.set('key3', 'value3');
map.delete('key2');
map.clear(); // Vide tout
// Vérification
map.has('key1'); // true
map.size; // Taille
// Itération (ordre d'insertion garanti)
for (const [key, value] of map) {
console.log(key, value);
}
map.forEach((value, key) => console.log(key, value));
// Clés, valeurs, entries
map.keys(); // Iterator des clés
map.values(); // Iterator des valeurs
map.entries(); // Iterator [key, value]
// Conversion
Object.fromEntries(map); // Vers objet
new Map(Object.entries(obj)); // Depuis objet
WeakSet et WeakMap
// WeakSet - références faibles, garbage collected
const weakSet = new WeakSet();
const obj = {};
weakSet.add(obj);
weakSet.has(obj); // true
weakSet.delete(obj);
// Pas de .size, pas itérable
// WeakMap - comme Map mais clés faibles
const weakMap = new WeakMap();
const key = {};
weakMap.set(key, 'value');
weakMap.get(key); // 'value'
weakMap.has(key); // true
weakMap.delete(key);
// Pas de .size, pas itérable
// Utilité: attacher metadata sans empêcher GC
Classes
Syntaxe basique
// Déclaration
class Person {
// Constructeur
constructor(nom, age) {
this.nom = nom;
this.age = age;
}
// Méthode
greet() {
return Bonjour, je suis ${this.nom};
}
// Getter
get info() {
return ${this.nom} (${this.age} ans);
}
// Setter
set nom(value) {
this.nom = value.trim();
}
get nom() {
return this.nom;
}
// Méthode statique
static create(nom, age) {
return new Person(nom, age);
}
// Propriété statique
static espece = 'Humain';
}
// Utilisation
const person = new Person('Jean', 30);
person.greet();
Person.create('Marie', 25);
Héritage
class Animal {
constructor(nom) {
this.nom = nom;
}
parler() {
return ${this.nom} fait un bruit;
}
}
class Chien extends Animal {
constructor(nom, race) {
super(nom); // Appel constructeur parent
this.race = race;
}
// Override
parler() {
return ${this.nom} aboie;
}
// Appeler méthode parente
parlerAnimal() {
return super.parler();
}
}
const chien = new Chien('Rex', 'Labrador');
chien.parler(); // 'Rex aboie'
chien instanceof Chien; // true
chien instanceof Animal; // true
Propriétés et méthodes privées
class BankAccount {
// Propriété privée (ES2022)
#balance = 0;
// Méthode privée
#calculateInterest() {
return this.#balance 0.05;
}
constructor(initialBalance) {
this.#balance = initialBalance;
}
deposit(amount) {
this.#balance += amount;
}
getBalance() {
return this.#balance;
}
}
const account = new BankAccount(100);
account.deposit(50);
account.getBalance(); // 150
// account.#balance; // Erreur - privé
Static blocks et champs (ES2022)
class Configuration {
static #apiKey;
static #apiUrl;
// Static initialization block
static {
this.#apiKey = process.env.APIKEY;
this.#apiUrl = process.env.APIURL;
console.log('Configuration loaded');
}
static getApiKey() {
return this.#apiKey;
}
}
Modules ES6
Export
// export.js
// Export nommé
export const PI = 3.14159;
export function add(a, b) {
return a + b;
}
export class User {
constructor(nom) {
this.nom = nom;
}
}
// Export groupé
const multiply = (a, b) => a b;
const divide = (a, b) => a / b;
export { multiply, divide };
// Export renommé
export { multiply as mult };
// Export default (un seul par module)
export default class Calculator {
add(a, b) { return a + b; }
}
// Ou
class Calculator {}
export default Calculator;
// Mix default + nommés
export default Calculator;
export { PI, add };
Import
// import.js
// Import default
import Calculator from './export.js';
// Import nommé
import { PI, add } from './export.js';
// Import renommé
import { multiply as mult } from './export.js';
// Import tout
import as math from './export.js';
math.PI;
math.add(1, 2);
// Mix default + nommés
import Calculator, { PI, add } from './export.js';
// Import dynamique (async)
const module = await import('./module.js');
module.default;
// Import avec condition
if (condition) {
const { feature } = await import('./feature.js');
}
// Re-export
export { add } from './math.js';
export from './utils.js';
export { default as Calculator } from './calc.js';
Promises et async
Promises
// Création
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
const success = true;
if (success) {
resolve('Succès');
} else {
reject('Erreur');
}
}, 1000);
});
// Utilisation
promise
.then(result => console.log(result))
.catch(error => console.error(error))
.finally(() => console.log('Terminé'));
// Chaînage
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
// Promise.all - toutes doivent réussir
Promise.all([promise1, promise2, promise3])
.then(([result1, result2, result3]) => {
console.log('Tous terminés');
});
// Promise.allSettled - attend toutes (ES2020)
Promise.allSettled([promise1, promise2, promise3])
.then(results => {
results.forEach(result => {
if (result.status === 'fulfilled') {
console.log('Succès:', result.value);
} else {
console.log('Erreur:', result.reason);
}
});
});
// Promise.race - première terminée
Promise.race([promise1, promise2])
.then(result => console.log('Premier:', result));
// Promise.any - première réussie (ES2021)
Promise.any([promise1, promise2, promise3])
.then(result => console.log('Premier succès:', result))
.catch(error => console.log('Toutes échouées'));
// Promise helpers
Promise.resolve(value); // Promise résolue
Promise.reject(error); // Promise rejetée
Async/Await avancé
// Gestion erreurs
async function fetchData(url) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(HTTP error! status: ${response.status});
}
return await response.json();
} catch (error) {
console.error('Fetch error:', error);
throw error;
}
}
// Parallèle avec Promise.all
async function getAllData() {
const [users, posts, comments] = await Promise.all([
fetchUsers(),
fetchPosts(),
fetchComments()
]);
return { users, posts, comments };
}
// Séquentiel
async function processSequential() {
const user = await fetchUser();
const posts = await fetchUserPosts(user.id);
const comments = await fetchPostComments(posts[0].id);
return { user, posts, comments };
}
// Avec timeout
async function fetchWithTimeout(url, timeout = 5000) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, { signal: controller.signal });
return await response.json();
} catch (error) {
if (error.name === 'AbortError') {
throw new Error('Request timeout');
}
throw error;
} finally {
clearTimeout(timeoutId);
}
}
// Retry logic
async function fetchWithRetry(url, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
return await fetch(url).then(r => r.json());
} catch (error) {
if (i === retries - 1) throw error;
await new Promise(resolve => setTimeout(resolve, 1000 (i + 1)));
}
}
}
DOM Manipulation
Sélection d’éléments
// Modern selectors
document.querySelector('#id'); // Premier élément
document.querySelector('.class');
document.querySelector('div.class');
document.querySelectorAll('.class'); // NodeList de tous
// Méthodes classiques
document.getElementById('id');
document.getElementsByClassName('class'); // HTMLCollection
document.getElementsByTagName('div');
// Traversal
element.closest('.parent'); // Ancêtre le plus proche
element.matches('.class'); // Teste si correspond au sélecteur
element.parentElement;
element.children; // HTMLCollection
element.firstElementChild;
element.lastElementChild;
element.nextElementSibling;
element.previousElementSibling;
Manipulation
// Contenu
element.textContent = 'Texte'; // Texte seul
element.innerHTML = 'HTML'; // HTML (attention XSS)
element.innerText = 'Texte visible'; // Texte visible (respecte CSS)
// Attributs
element.getAttribute('data-id');
element.setAttribute('data-id', '123');
element.removeAttribute('data-id');
element.hasAttribute('data-id');
// Data attributes
element.dataset.id = '123'; // data-id="123"
element.dataset.userId; // data-user-id
// Classes
element.classList.add('class1', 'class2');
element.classList.remove('class1');
element.classList.toggle('active');
element.classList.contains('active');
element.classList.replace('old', 'new');
// Style
element.style.color = 'red';
element.style.backgroundColor = 'blue';
element.style.display = 'none';
element.style.cssText = 'color: red; background: blue;';
// Computed style
getComputedStyle(element).color;
// Création
const div = document.createElement('div');
div.className = 'my-class';
div.id = 'my-id';
div.textContent = 'Contenu';
// Insertion
parent.appendChild(div);
parent.append(div, 'texte', otherElement); // Multiple
parent.prepend(div); // Au début
parent.insertBefore(div, referenceElement);
element.insertAdjacentElement('beforebegin', div); // Avant element
element.insertAdjacentElement('afterbegin', div); // Début de element
element.insertAdjacentElement('beforeend', div); // Fin de element
element.insertAdjacentElement('afterend', div); // Après element
// Suppression
element.remove();
parent.removeChild(element);
// Remplacement
parent.replaceChild(newElement, oldElement);
element.replaceWith(newElement);
// Clone
const clone = element.cloneNode(true); // true = deep clone
Événements
// addEventListener (moderne)
element.addEventListener('click', (event) => {
console.log('Cliqué!');
event.preventDefault(); // Empêche comportement par défaut
event.stopPropagation(); // Arrête propagation
});
// Options
element.addEventListener('click', handler, {
once: true, // Se retire après 1 appel
passive: true, // Ne peut pas preventDefault
capture: true // Phase capture
});
// Retirer listener
element.removeEventListener('click', handler);
// Événements courants
element.addEventListener('click', handler);
element.addEventListener('dblclick', handler);
element.addEventListener('mouseenter', handler);
element.addEventListener('mouseleave', handler);
element.addEventListener('mousemove', handler);
element.addEventListener('keydown', handler);
element.addEventListener('keyup', handler);
element.addEventListener('input', handler); // Tout changement input
element.addEventListener('change', handler); // Changement validé
element.addEventListener('submit', handler);
element.addEventListener('focus', handler);
element.addEventListener('blur', handler);
element.addEventListener('scroll', handler);
element.addEventListener('resize', handler);
// Event object
function handleClick(event) {
event.target; // Élément cliqué
event.currentTarget; // Élément avec listener
event.type; // Type d'événement
event.key; // Touche clavier
event.clientX, event.clientY; // Position souris
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation(); // Arrête tous handlers
}
// Délégation d'événements
document.querySelector('.list').addEventListener('click', (event) => {
if (event.target.matches('.item')) {
console.log('Item cliqué:', event.target);
}
});
// Custom events
const customEvent = new CustomEvent('myEvent', {
detail: { message: 'Hello' },
bubbles: true,
cancelable: true
});
element.dispatchEvent(customEvent);
element.addEventListener('myEvent', (event) => {
console.log(event.detail.message);
});
Fetch API
// GET simple
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
// Avec async/await
async function getData() {
try {
const response = await fetch('https://api.example.com/data');
if (!response.ok) {
throw new Error(HTTP error! status: ${response.status});
}
const data = await response.json();
return data;
} catch (error) {
console.error('Fetch error:', error);
}
}
// POST avec JSON
fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
nom: 'Jean',
email: 'jean@example.com'
})
})
.then(response => response.json())
.then(data => console.log(data));
// Autres méthodes
fetch(url, { method: 'PUT', body: JSON.stringify(data) });
fetch(url, { method: 'PATCH', body: JSON.stringify(data) });
fetch(url, { method: 'DELETE' });
// Headers
fetch(url, {
headers: {
'Authorization': 'Bearer token',
'Content-Type': 'application/json',
'X-Custom-Header': 'value'
}
});
// FormData
const formData = new FormData();
formData.append('nom', 'Jean');
formData.append('file', fileInput.files[0]);
fetch(url, {
method: 'POST',
body: formData
});
// Abort (cancel request)
const controller = new AbortController();
fetch(url, { signal: controller.signal })
.then(response => response.json())
.catch(error => {
if (error.name === 'AbortError') {
console.log('Request cancelled');
}
});
// Cancel après timeout
setTimeout(() => controller.abort(), 5000);
// Response methods
response.json(); // Parse JSON
response.text(); // Texte brut
response.blob(); // Blob (fichiers)
response.arrayBuffer(); // ArrayBuffer
response.formData(); // FormData
// Response properties
response.ok; // true si 200-299
response.status; // Code HTTP
response.statusText; // Message HTTP
response.headers.get('content-type');
Utilitaires et patterns
String methods
const str = 'Hello World';
// Recherche
str.includes('World'); // true
str.startsWith('Hello'); // true
str.endsWith('World'); // true
str.indexOf('World'); // 6
str.lastIndexOf('o'); // 7
str.search(/world/i); // 6 (regex)
// Extraction
str.slice(0, 5); // 'Hello'
str.substring(0, 5); // 'Hello'
str.substr(0, 5); // 'Hello' (déprécié)
str.charAt(0); // 'H'
str.at(-1); // 'd' (ES2022)
// Transformation
str.toLowerCase();
str.toUpperCase();
str.trim(); // Retire espaces début/fin
str.trimStart(); // Début seulement
str.trimEnd(); // Fin seulement
str.padStart(10, '0'); // '000Hello World'
str.padEnd(15, '.'); // 'Hello World....'
str.repeat(3); // 'Hello WorldHello WorldHello World'
str.replace('World', 'JS'); // 'Hello JS'
str.replaceAll('o', '0'); // 'Hell0 W0rld'
// Split/Join
str.split(' '); // ['Hello', 'World']
str.split(''); // ['H', 'e', 'l', ...]
['Hello', 'World'].join(' '); // 'Hello World'
// Match
str.match(/[A-Z]/g); // ['H', 'W']
str.matchAll(/[a-z]/g); // Iterator
// Template literals
const name = 'Jean';
const age = 30;
const message = ${name} a ${age} ans;
const multiline = `
Ligne 1
Ligne 2
`;
// Tagged templates
function highlight(strings, ...values) {
return strings.reduce((acc, str, i) => {
return acc + str + (values[i] ? ${values[i]} : '');
}, '');
}
const html = highlightLe prix est ${price} euros;
Number methods
// Parsing
parseInt('42'); // 42
parseInt('42px'); // 42
parseInt('1010', 2); // 10 (binaire)
parseFloat('3.14'); // 3.14
Number('42'); // 42
Number('42px'); // NaN
// Vérification
Number.isNaN(NaN); // true
Number.isFinite(42); // true
Number.isInteger(42); // true
Number.isSafeInteger(42); // true
// Formatage
const num = 1234.567;
num.toFixed(2); // '1234.57'
num.toPrecision(4); // '1235'
num.toExponential(2); // '1.23e+3'
num.toLocaleString('fr-FR'); // '1 234,567'
num.toLocaleString('fr-FR', {
style: 'currency',
currency: 'EUR'
}); // '1 234,57 €'
// Constantes
Number.MAXVALUE;
Number.MINVALUE;
Number.MAXSAFEINTEGER; // 2^53 - 1
Number.MINSAFEINTEGER;
Number.POSITIVEINFINITY;
Number.NEGATIVEINFINITY;
Number.EPSILON;
// Math
Math.abs(-5); // 5
Math.ceil(4.3); // 5
Math.floor(4.7); // 4
Math.round(4.5); // 5
Math.trunc(4.7); // 4 (retire décimales)
Math.max(1, 5, 3); // 5
Math.min(1, 5, 3); // 1
Math.pow(2, 3); // 8
Math.sqrt(16); // 4
Math.random(); // 0-1
Math.PI;
Math.E;
Date et Time
// Création
new Date(); // Maintenant
new Date('2024-12-18');
new Date('2024-12-18T10:30:00');
new Date(2024, 11, 18); // 18 décembre 2024 (mois 0-11)
new Date(timestamp);
// Timestamp
Date.now(); // Millisecondes depuis 1970
date.getTime();
// Get
date.getFullYear(); // 2024
date.getMonth(); // 0-11 (11 = décembre)
date.getDate(); // 1-31
date.getDay(); // 0-6 (0 = dimanche)
date.getHours(); // 0-23
date.getMinutes(); // 0-59
date.getSeconds(); // 0-59
date.getMilliseconds(); // 0-999
// Set
date.setFullYear(2025);
date.setMonth(11);
date.setDate(25);
date.setHours(12);
// Format
date.toString(); // "Wed Dec 18 2024 10:30:00 GMT+0100"
date.toISOString(); // "2024-12-18T09:30:00.000Z"
date.toLocaleDateString('fr-FR'); // "18/12/2024"
date.toLocaleTimeString('fr-FR'); // "10:30:00"
date.toLocaleString('fr-FR'); // "18/12/2024 10:30:00"
// Intl.DateTimeFormat (moderne)
const formatter = new Intl.DateTimeFormat('fr-FR', {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
});
formatter.format(date); // "18 décembre 2024 à 10:30"
// Différence
const diff = date2 - date1; // Millisecondes
const days = diff / (1000 60 60 24);
Regex (expressions régulières)
// Création
const regex1 = /pattern/flags;
const regex2 = new RegExp('pattern', 'flags');
// Flags
// g - global (tous matches)
// i - insensible casse
// m - multiline
// s - dotAll (. match newline)
// u - unicode
// y - sticky
// Test
/hello/i.test('Hello World'); // true
// Match
'Hello World'.match(/[A-Z]/g); // ['H', 'W']
'Hello World'.match(/(w+) (w+)/); // ['Hello World', 'Hello', 'World']
// MatchAll
const matches = 'test1 test2 test3'.matchAll(/test(d)/g);
for (const match of matches) {
console.log(match[0], match[1]);
}
// Replace
'Hello World'.replace(/World/, 'JS'); // 'Hello JS'
'test1 test2'.replace(/test(d)/g, 'item$1'); // 'item1 item2'
'test'.replace(/t/g, (match) => match.toUpperCase()); // 'TesT'
// Split
'a,b,c'.split(/,/); // ['a', 'b', 'c']
// Patterns utiles
/^d+$/; // Nombres uniquement
/^[a-zA-Z]+$/; // Lettres uniquement
/^[w-.]+@([w-]+.)+[w-]{2,4}$/; // Email basique
/^https?:///; // URL
/^d{5}$/; // Code postal 5 chiffres
/^0[1-9]d{8}$/; // Téléphone français
Bonnes pratiques
Performance
// Debounce - limite appels rapides
function debounce(func, delay) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func.apply(this, args), delay);
};
}
const handleResize = debounce(() => {
console.log('Window resized');
}, 250);
window.addEventListener('resize', handleResize);
// Throttle - max un appel par période
function throttle(func, limit) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
const handleScroll = throttle(() => {
console.log('Scrolling');
}, 100);
window.addEventListener('scroll', handleScroll);
// Memoization
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;
};
}
const fibonacci = memoize((n) => {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
});
Patterns modernes
// Optional chaining avec méthodes
obj?.method?.();
arr?.[0]?.property;
// Nullish coalescing pour defaults
const config = {
timeout: userConfig?.timeout ?? 5000,
retries: userConfig?.retries ?? 3
};
// Object shorthand
const name = 'Jean';
const age = 30;
const user = { name, age };
// Destructuring avec defaults
function greet({ name = 'Guest', greeting = 'Hello' } = {}) {
return ${greeting}, ${name}!;
}
// Array methods chaining
users
.filter(u => u.active)
.map(u => u.name)
.sort()
.slice(0, 10);
// Async iteration
for await (const item of asyncIterator) {
console.log(item);
}
---
Version: ES2024 (ECMAScript 2024) | Compatibilité: Navigateurs modernes