Skip to Content
FrontendJavaScript ES6+

JavaScript ES6+ — Guide pratique

Syntaxe moderne de JavaScript (ES2015 et au-delĂ ) — let/const, flĂšches, dĂ©structuration, spread/rest, modules ES, Promises, async/await, optional chaining et nullish coalescing.

Cette page est un complément à Frontend. Elle se concentre sur les mécanismes de langage ES6+.


let et const — remplacement de var

var déclare une variable portée au bloc le plus proche fonction, pas au bloc if/for/while. let et const sont portés au bloc { ... }.

// var — portĂ©e fonction, pas de bloc function demoVar() { if (true) { var x = 10; } console.log(x); // 10 ← visible hors du bloc } // let / const — portĂ©e bloc function demoBlock() { if (true) { let y = 10; const z = 20; } console.log(y); // ReferenceError console.log(z); // ReferenceError }

Pitfall : var dans une boucle for crĂ©e un seul binding partagĂ© — les closures captent la mĂȘme variable. Utiliser let pour la boucle dans ce cas.

Dead zone (TDZ)

Une variable let/const existe avant son initialisation, mais son accĂšs lĂšve ReferenceError jusqu’à la dĂ©claration.

console.log(a); // ReferenceError (TDZ) let a = 10; console.log(a); // 10 // Fonctionne — const est initialisĂ© AVANT d'ĂȘtre utilisĂ© const b = 42; console.log(b); // 42

Pitfall : const signifie « liaison constante », pas « valeur constante ». L’objet liĂ© peut ĂȘtre mutĂ©.

const tab = []; tab.push(1); // OK — la rĂ©fĂ©rence ne change pas tab = []; // TypeError : Assignment to constant variable

Fonctions fléchées

Syntaxe courte pour les fonctions. Deux différences fondamentales avec function classique :

  1. Pas de this propre — elles hĂ©ritent du this du contexte lexical (celui du parent).
  2. Pas de arguments — le mot-clĂ© arguments n’existe pas dans une flĂ©chĂ©e.
// Fonction classique — this liĂ© Ă  l'objet appelant const obj = { nom: 'Arthur', saluer: function() { return `Bonjour, je suis ${this.nom}`; }, // Fonction flĂ©chĂ©e — this hĂ©ritĂ© (globale ici, undefined en mode strict) saluerFlĂ©chĂ©e: () => { return `Bonjour, je suis ${this.nom}`; // undefined } }; // Usage pratique : callback avec `this` prĂ©servĂ© class Compteur { constructor() { this.valeur = 0; // setInterval avec flĂ©chĂ©e : `this` reste le compteur setInterval(() => { this.valeur++; }, 1000); } }

RĂšgle simple : utiliser une flĂ©chĂ©e pour les callbacks et les mĂ©thodes sans besoin de this. RĂ©server function classique pour les mĂ©thodes d’objet et les constructeurs.

Pitfall : les flĂ©chĂ©es ne peuvent PAS ĂȘtre utilisĂ©es comme constructeurs. new (() => {}) lĂšve TypeError.


Déstructuring

Extraire des valeurs d’objets et de tableaux avec une syntaxe expressive.

Objets

const config = { host: 'localhost', port: 3000, debug: true }; // Extraire avec renommage const { host: h, port: p, debug } = config; // h = 'localhost', p = 3000, debug = true // Valeurs par défaut (uniquement pour `undefined`) const { timeout = 5000, retries = 3 } = config; // timeout = 5000, retries = 3 (config n'a pas ces clés) // Capturer le reste avec spread const { debug, ...sansDebug } = config; // sansDebug = { host: 'localhost', port: 3000 }

Tableaux

const couleurs = ['rouge', 'vert', 'bleu']; // Extraire des positions spĂ©cifiques const [, milieu, fin] = couleurs; // milieu = 'vert', fin = 'bleu' // Capturer le reste const [premier, ...lesAutres] = couleurs; // premier = 'rouge', lesAutres = ['vert', 'bleu'] // Échanger deux variables (sans variable temporaire) let a = 1, b = 2; [a, b] = [b, a]; // a = 2, b = 1

Imbriquée

const réponse = { données: { utilisateurs: [ { nom: 'Alice', ùge: 30 }, { nom: 'Bob', ùge: 25 } ], meta: { page: 1, total: 42 } } }; const { données: { utilisateurs: list, meta: { page } } } = réponse; list[0].nom; // 'Alice' page; // 1

Pitfall : déstructurer une valeur null ou undefined lÚve TypeError. Toujours protéger : const { x } = obj ?? {}; ou const { x } = (obj || {});.


Spread (...) et opérateurs rest

Le mĂȘme syntaxe ... a deux usages distincts selon le contexte.

Spread — « Ă©tendre » un itĂ©rable

// Tableaux const combinĂ© = [...tableauA, ...tableauB]; const copiĂ© = [...original]; // Objets (shallow merge, derniĂšres clĂ©s Ă©crasent) const combinĂ©Obj = { ...cible, ...origine }; // Si les deux ont la mĂȘme clĂ©, origine gagne. // Passer un tableau comme arguments const max = Math.max(...[3, 1, 4, 1, 5]);

Rest — « capturer le reste » dans une dĂ©claration

// Déstructuring objet const { password, ...user } = donnéesUtilisateur; // user = tout sauf password // Déstructuring tableau const [premier, ...reste] = [1, 2, 3, 4]; // reste = [2, 3, 4] // ParamÚtres variadiques function somme(...nombres) { return nombres.reduce((acc, n) => acc + n, 0); } somme(1, 2, 3); // 6

Différence clé : le spread « démonte » un tableau/objet en éléments individuels ; le rest « monte » des éléments en un tableau/objet unique.


Template literals

ChaĂźnes multi-lignes et interpolation de expressions avec le backtick `.

const nom = 'Arthur'; const ùge = 30; // Interpolation const salutation = `Bonjour, je suis ${nom}, ${ùge} ans.`; // Multi-lignes (sans `\n` explicites) const message = ` Ligne 1 Ligne 2 Ligne 3 `; // Expression complÚte dans ${ } const arr = [1, 2, 3]; const résumé = `Le tableau contient ${arr.length} éléments : ${arr.join(', ')}.`; // 'Le tableau contient 3 éléments : 1, 2, 3.'

Tagged templates

Appeler une fonction personnalisée pour traiter le template. Utile pour le formatage ou la sécurité (échappement HTML).

// Fonction tag : reçoit les parties de chaßne et les expressions function escapeHTML(strings, ...valeurs) { return strings.reduce((resultat, partie, i) => { const val = i < valeurs.length ? String(valeurs[i]).replace(/</g, '&lt;').replace(/>/g, '&gt;') : ''; return résultat + partie + val; }, ''); } const user = '<script>alert("xss")</script>'; const sécurisé = escapeHTML`Bienvenue, ${user} !`; // 'Bienvenue, &lt;script&gt;alert("xss")&lt;/script&gt; !'

Modules ES (import / export)

Remplacement de require() (CommonJS) et module.exports. Syntaxe déclarative, analyse statique possible, support natif dans tous les navigateurs modernes.

// module.js — Exportations export const PI = 3.14159; export function aire(rayon) { return PI * rayon * rayon; } // Export nommĂ© par dĂ©faut export default function Racine(r) { return Math.sqrt(r); }
// autre-module.js — Importations // Importation spĂ©cifique import { PI, aire } from './module.js'; // Renommer Ă  l'import import { PI as Pi } from './module.js'; // Import par dĂ©faut import Racine from './module.js'; // Importer les deux en mĂȘme temps import Racine, { PI, aire } from './module.js'; // Importer TOUT dans un namespace import * as maths from './module.js'; maths.PI; maths.aire(5); // Import dynamique (chargement tardif) import('./module.js').then(m => { m.aire(10); });

Import dynamique vs statique : les import statiques sont rĂ©solus au chargement du module. Les imports dynamiques (import()) retournent une Promise — utiles pour le code lazy-loaded (routes, plugins).

Pitfall : les exports default ne sont pas verrouillĂ©s par le linter. Un mĂȘme module ne peut avoir qu’un seul export default.


Promises et async/await

Promise — pattern asynchrone

Une Promise représente une opération asynchrone en trois états : pending, fulfilled, rejected.

// Création manuelle (rare) const p = new Promise((résoudre, rejetter) => { if (donnéesValides) { résoudre(données); } else { rejetter(new Error('Données invalides')); } }); // Chaßnage `.then()` / `.catch()` chargerDonnées() .then(traiter) .then(afficher) .catch(erreur => console.error(erreur));

async/await — syntaxe synchronisĂ©e

async dĂ©clare une fonction qui retourne implicitement une Promise. await suspend l’exĂ©cution jusqu’à ce que la Promise soit rĂ©solue.

async function chargerEtAfficher() { try { const users = await fetch('/api/users').then(r => r.json()); const posts = await fetch('/api/posts').then(r => r.json()); console.log(users, posts); } catch (erreur) { console.error('Erreur:', erreur.message); } } chargerEtAfficher();

Parallélisation

await séquentiel = somme des durées. Promise.all() = durée du plus long.

// Séquentiel (lent) const a = await fetch('/api/a'); // 200ms const b = await fetch('/api/b'); // 300ms // Total : ~500ms // ParallÚle (rapide) const [a, b] = await Promise.all([ fetch('/api/a'), fetch('/api/b') ]); // Total : ~300ms (le plus long des deux) // Si un seul échoue, toute la chaßne échoue const résultat = await Promise.allSettled([ fetch('/api/a'), fetch('/api/échec') ]); // Pour inspecter chaque résultat sans échouer brutalement

Pitfall : await ne fait pas planter la fonction — il rejette la Promise retour. Capturer avec try/catch ou .catch() pour Ă©viter un Unhandled Promise Rejection.


Optional chaining (?.) et nullish coalescing (??)

Optional chaining

Accéder à une propriété ou appeler une méthode sans lever TypeError si la valeur intermédiaire est null/undefined.

const utilisateur = { profil: { nom: 'Alice', adresse: { ville: 'Paris' } } }; // Sans optional chaining : utilisateur.profil.adresse.codePostal; // undefined (pas d'erreur) utilisateur.inconnu.clef; // TypeError ! // Avec optional chaining : utilisateur.profil?.nom; // 'Alice' utilisateur.inconnu?.clef; // undefined (pas d'erreur) utilisateur.profil?.adresse?.ville; // 'Paris' // Appel de méthode sécurisé const résultat = utilisateur.fetcher?.(données); // si fetcher est undefined, résultat = undefined (pas d'erreur)

Nullish coalescing

Retourne le cÎté droit si la gauche est null ou undefined (pas si false, 0, ou '').

// OpĂ©rateur `||` — falsy (faux, 0, '', null, undefined) const message = '' || 'dĂ©faut'; // 'dĂ©faut' ← souvent indĂ©sirable // OpĂ©rateur `??` — nullish uniquement const message = '' ?? 'dĂ©faut'; // '' ← prĂ©servĂ© const valeur = null ?? 42; // 42 const zĂ©ro = 0 ?? 42; // 0 // ChaĂźnage avec optional chaining const hauteur = objet?.dimensions?.hauteur ?? 100;

Différence clé : || remplace false, 0, '' ; ?? ne remplace que null et undefined.


RĂ©capitulatif — quand utiliser quoi

BesoinSolution ES6+
Variable bloclet / const (jamais var)
Méthode simple, pas de thisFonction fléchée
MĂ©thode d’objet, this nĂ©cessairefunction classique
Extraire des valeursDéstructuring
Fusionner / clonerSpread ...
ParamĂštres variablesRest ...args
ChaĂźne avec variablesTemplate literal `
Module structurelimport / export
Code asynchroneasync / await
AccÚs sûr à propriétéOptional chaining ?.
Valeur par défaut sécuriséeNullish coalescing ??

PiĂšges courants

PiĂšgeSymptĂŽmeCorrection
const mutĂ©TypeError Ă  l’affectationUtiliser let si la rĂ©fĂ©rence change ; structuredClone() pour une copie profonde
this dans flĂ©chĂ©ethis = undefined dans mĂ©thode d’objetPasser en function classique
arguments dans fléchéeReferenceErrorUtiliser les paramÚtres rest ...args
var dans une boucleClosure captant la mĂȘme variableRemplacer var par let
Template literal avec \ à la finEspace blanc indésirable dans multi-lignesUtiliser ${''} ou supprimer le \
Promise non-géréeUnhandled Promise RejectionToujours ajouter .catch() ou utiliser async/await avec try/catch
Optional chaining sur le cĂŽtĂ© gauche d’une affectationSyntaxErrorUtiliser {}, objet placeholder ou mĂ©thode d’affectation conditionnelle