JavaScript moderne (ES6+) : le guide complet pour maîtriser JS en 2025

Maîtrisez JavaScript moderne avec ES6+ : variables, fonctions fléchées, promesses, async/await et modules. Le guide indispensable entre HTML/CSS et React/Angular.

JavaScript moderne : bienvenue dans l'ère ES6+

Tu as appris HTML et CSS, et maintenant tu veux rendre tes pages interactives ? JavaScript est LE langage incontournable du web. Mais attention : le JavaScript d'aujourd'hui n'a rien à voir avec celui d'il y a 10 ans !

Depuis ES6 (ECMAScript 2015), JavaScript a connu une révolution. De nouvelles fonctionnalités puissantes ont transformé le langage : arrow functions, promesses, async/await, destructuring, modules... Si tu veux coder moderne et te préparer à React, Angular ou Node.js, tu DOIS maîtriser ces concepts.

Ce guide complet te prend par la main, du niveau zéro jusqu'aux concepts avancés. À la fin, tu seras prêt à créer des applications web interactives et à plonger dans les frameworks modernes. Let's go ! 🚀


Pourquoi apprendre JavaScript moderne ?

  • 🌐 Le langage du web : Tous les sites interactifs utilisent JavaScript
  • Fullstack possible : Frontend (React, Vue) ET backend (Node.js) avec un seul langage
  • 📱 Apps mobiles : React Native te permet de créer des apps iOS/Android
  • 🎯 Très demandé : JavaScript est dans le top 3 des langages les plus recherchés
  • 🔥 Écosystème riche : Des millions de bibliothèques sur npm
  • 💼 Salaires attractifs : Les développeurs JavaScript sont très bien payés

Les bases essentielles avant ES6

Avant de plonger dans le moderne, assurons-nous que tu maîtrises les fondamentaux !

Intégrer JavaScript dans ton HTML

Il existe 3 façons d'ajouter du JavaScript :

1. JavaScript inline (dans la balise) ❌ À éviter

<button onclick="alert('Hello')">Clique-moi</button>

2. JavaScript interne (dans le HTML)

<script>
  console.log('Hello World!');
</script>

3. JavaScript externe (fichier séparé) ✅ RECOMMANDÉ

<script src="script.js"></script>

💡 Astuce : Place toujours ton <script> juste avant la balise </body> pour que le HTML charge d'abord.


Variables : let, const et var (enfin une clarification !)

En JavaScript moderne, on utilise let et const au lieu de var. Voici pourquoi :

var : l'ancien système (à oublier)

var age = 25;
var age = 30; // ❌ Redéclaration possible = bugs potentiels
console.log(age); // 30

Problème de var : portée (scope) étrange, hoisting bizarre, redéclaration autorisée.


let : pour les variables qui changent

let age = 25;
age = 30; // ✅ Modification OK
let age = 35; // ❌ Erreur : redéclaration interdite
console.log(age); // 30

Utilise let pour les valeurs qui vont changer (compteurs, formulaires, etc.).


const : pour les valeurs constantes

const PI = 3.14159;
PI = 3.14; // ❌ Erreur : réassignation interdite

const user = { name: 'Alex' };
user.name = 'Marie'; // ✅ OK : on modifie le contenu, pas la référence
user = {}; // ❌ Erreur : réassignation de la variable

Utilise const par défaut, et let uniquement si tu as besoin de modifier la variable.


La portée de bloc (block scope)

if (true) {
  let x = 10;
  const y = 20;
}
console.log(x); // ❌ Erreur : x n'existe que dans le bloc if

let et const sont limités au bloc {} où ils sont déclarés. Plus de fuites de variables !


Les types de données en JavaScript

JavaScript a 7 types primitifs :

// 1. String (texte)
const nom = "Alexandre";
const prenom = 'Marie';
const phrase = `Bonjour ${nom}`; // Template literal

// 2. Number (nombres)
const age = 25;
const prix = 19.99;

// 3. Boolean (vrai/faux)
const estMajeur = true;
const estConnecte = false;

// 4. Undefined (non défini)
let variable; // undefined

// 5. Null (valeur nulle volontaire)
const valeur = null;

// 6. Symbol (identifiant unique)
const id = Symbol('id');

// 7. BigInt (très grands nombres)
const bigNumber = 9007199254740991n;

Opérateurs essentiels

// Arithmétiques
let a = 10 + 5;  // 15
let b = 10 - 5;  // 5
let c = 10 * 5;  // 50
let d = 10 / 5;  // 2
let e = 10 % 3;  // 1 (reste de la division)
let f = 10 ** 2; // 100 (puissance)

// Comparaison
5 === 5;   // true (égalité stricte)
5 == "5";  // true (égalité souple, à éviter)
5 !== 6;   // true (différent)
5 > 3;     // true
5 <= 5;    // true

// Logiques
true && false;  // false (ET)
true || false;  // true (OU)
!true;          // false (NON)

⚠️ Toujours utiliser === et !== (égalité stricte) au lieu de == et !=.


Arrow Functions : la révolution ES6

Les fonctions fléchées sont plus concises et ont un comportement différent avec this.

Syntaxe classique vs Arrow function

// Fonction classique
function addition(a, b) {
  return a + b;
}

// Arrow function équivalente
const addition = (a, b) => {
  return a + b;
};

// Arrow function ultra-concise (return implicite)
const addition = (a, b) => a + b;

console.log(addition(5, 3)); // 8

Règles de syntaxe des arrow functions

// Un seul paramètre : parenthèses optionnelles
const double = x => x * 2;

// Zéro paramètre : parenthèses obligatoires
const saluer = () => console.log('Hello!');

// Plusieurs paramètres : parenthèses obligatoires
const multiplier = (a, b) => a * b;

// Plusieurs lignes : accolades et return explicite
const calculer = (x, y) => {
  const somme = x + y;
  return somme * 2;
};

Différence importante avec this

const personne = {
  nom: 'Alex',
  // Fonction classique : this = personne
  direBonjour: function() {
    console.log(`Bonjour, je suis ${this.nom}`);
  },
  // Arrow function : this = contexte parent (pas personne)
  direBonjourArrow: () => {
    console.log(`Bonjour, je suis ${this.nom}`); // undefined
  }
};

personne.direBonjour(); // "Bonjour, je suis Alex"
personne.direBonjourArrow(); // "Bonjour, je suis undefined"

💡 Règle : Utilise les arrow functions SAUF pour les méthodes d'objets.


Template Literals : fini la concaténation moche

Les template literals (backticks) rendent l'interpolation de chaînes super simple :

// Avant ES6 (moche)
const nom = 'Alexandre';
const age = 28;
const message = 'Je m'appelle ' + nom + ' et j'ai ' + age + ' ans.';

// Avec ES6 (élégant)
const message = `Je m'appelle ${nom} et j'ai ${age} ans.`;

// Multiligne facile
const html = `
  <div>
    <h1>${nom}</h1>
    <p>Age : ${age}</p>
  </div>
`;

// Expressions dans les templates
const prix = 19.99;
console.log(`Prix TTC : ${prix * 1.2}€`); // Prix TTC : 23.988€

Destructuring : extraire des valeurs facilement

Le destructuring permet d'extraire des valeurs d'objets ou de tableaux de manière concise.

Destructuring d'objets

const user = {
  nom: 'Alexandre',
  age: 28,
  ville: 'Tours'
};

// Avant ES6
const nom = user.nom;
const age = user.age;

// Avec destructuring
const { nom, age, ville } = user;
console.log(nom);  // 'Alexandre'
console.log(age);  // 28

// Renommer une variable
const { nom: userName, age: userAge } = user;

// Valeur par défaut
const { pays = 'France' } = user;
console.log(pays); // 'France'

Destructuring de tableaux

const couleurs = ['rouge', 'vert', 'bleu'];

// Avant ES6
const premiere = couleurs[0];
const deuxieme = couleurs[1];

// Avec destructuring
const [premiere, deuxieme, troisieme] = couleurs;
console.log(premiere); // 'rouge'

// Ignorer des éléments
const [, , troisieme] = couleurs; // Ignore les 2 premiers

// Rest operator
const [first, ...rest] = couleurs;
console.log(first); // 'rouge'
console.log(rest);  // ['vert', 'bleu']

Destructuring dans les paramètres de fonction

// Super pratique pour les fonctions
const afficherUser = ({ nom, age }) => {
  console.log(`${nom} a ${age} ans`);
};

const user = { nom: 'Alex', age: 28 };
afficherUser(user); // 'Alex a 28 ans'

Spread et Rest Operators : ... magique

L'opérateur ... a deux usages selon le contexte :

Spread operator : étaler les éléments

// Copier un tableau
const arr1 = [1, 2, 3];
const arr2 = [...arr1]; // [1, 2, 3]

// Fusionner des tableaux
const nombres = [1, 2, 3];
const lettres = ['a', 'b', 'c'];
const fusion = [...nombres, ...lettres]; // [1, 2, 3, 'a', 'b', 'c']

// Copier un objet
const user = { nom: 'Alex', age: 28 };
const userCopy = { ...user }; // { nom: 'Alex', age: 28 }

// Fusionner des objets
const adresse = { ville: 'Tours', pays: 'France' };
const userComplet = { ...user, ...adresse };
// { nom: 'Alex', age: 28, ville: 'Tours', pays: 'France' }

// Passer des arguments à une fonction
const max = Math.max(...[5, 10, 2, 8]); // 10

Rest operator : rassembler les éléments

// Dans les paramètres de fonction
const somme = (...nombres) => {
  return nombres.reduce((acc, n) => acc + n, 0);
};

console.log(somme(1, 2, 3, 4, 5)); // 15

// Dans le destructuring
const [first, second, ...reste] = [1, 2, 3, 4, 5];
console.log(reste); // [3, 4, 5]

const { nom, ...autresInfos } = { nom: 'Alex', age: 28, ville: 'Tours' };
console.log(autresInfos); // { age: 28, ville: 'Tours' }

Méthodes de tableaux essentielles

JavaScript moderne offre des méthodes puissantes pour manipuler les tableaux sans boucles manuelles.

map() : transformer chaque élément

const nombres = [1, 2, 3, 4, 5];
const doubles = nombres.map(n => n * 2);
console.log(doubles); // [2, 4, 6, 8, 10]

const users = [
  { nom: 'Alex', age: 28 },
  { nom: 'Marie', age: 25 }
];
const noms = users.map(user => user.nom);
console.log(noms); // ['Alex', 'Marie']

filter() : filtrer les éléments

const nombres = [1, 2, 3, 4, 5, 6];
const pairs = nombres.filter(n => n % 2 === 0);
console.log(pairs); // [2, 4, 6]

const users = [
  { nom: 'Alex', age: 28 },
  { nom: 'Marie', age: 17 }
];
const majeurs = users.filter(user => user.age >= 18);
console.log(majeurs); // [{ nom: 'Alex', age: 28 }]

reduce() : réduire à une seule valeur

const nombres = [1, 2, 3, 4, 5];
const somme = nombres.reduce((acc, n) => acc + n, 0);
console.log(somme); // 15

const panier = [
  { nom: 'Livre', prix: 15 },
  { nom: 'Stylo', prix: 2 },
  { nom: 'Cahier', prix: 5 }
];
const total = panier.reduce((acc, item) => acc + item.prix, 0);
console.log(total); // 22

find() et findIndex()

const users = [
  { id: 1, nom: 'Alex' },
  { id: 2, nom: 'Marie' },
  { id: 3, nom: 'Paul' }
];

const user = users.find(u => u.id === 2);
console.log(user); // { id: 2, nom: 'Marie' }

const index = users.findIndex(u => u.id === 2);
console.log(index); // 1

some() et every()

const nombres = [2, 4, 6, 8];

const tousVPairs = nombres.every(n => n % 2 === 0);
console.log(tousPairs); // true

const auMoinsUnPair = nombres.some(n => n % 2 === 0);
console.log(auMoinsUnPair); // true

Promesses : gérer l'asynchrone proprement

Les Promises permettent de gérer les opérations asynchrones (appels API, timers, etc.) de manière élégante.

Créer une Promise

const maPromesse = new Promise((resolve, reject) => {
  const succes = true;

  setTimeout(() => {
    if (succes) {
      resolve('Opération réussie !');
    } else {
      reject('Erreur survenue');
    }
  }, 2000);
});

// Utiliser la Promise
maPromesse
  .then(resultat => console.log(resultat))
  .catch(erreur => console.error(erreur));

Chaîner les Promises

fetch('https://api.example.com/users')
  .then(response => response.json())
  .then(users => console.log(users))
  .catch(error => console.error('Erreur:', error));

Async/Await : les Promises en plus lisible

async/await est du sucre syntaxique au-dessus des Promises. C'est LA façon moderne d'écrire du code asynchrone.

Syntaxe async/await

// Avec Promises (verbeux)
function getUsers() {
  return fetch('https://api.example.com/users')
    .then(response => response.json())
    .then(users => {
      console.log(users);
      return users;
    })
    .catch(error => console.error(error));
}

// Avec async/await (élégant)
async function getUsers() {
  try {
    const response = await fetch('https://api.example.com/users');
    const users = await response.json();
    console.log(users);
    return users;
  } catch (error) {
    console.error('Erreur:', error);
  }
}

Règles d'async/await

  • await ne fonctionne QUE dans une fonction async
  • Une fonction async retourne toujours une Promise
  • Utilise try/catch pour gérer les erreurs
async function fetchData() {
  const response = await fetch('/api/data');
  return response.json();
}

// Utilisation
fetchData()
  .then(data => console.log(data))
  .catch(err => console.error(err));

Paralléliser les requêtes avec Promise.all()

// Séquentiel (lent)
async function getDataSequential() {
  const users = await fetch('/api/users').then(r => r.json());
  const posts = await fetch('/api/posts').then(r => r.json());
  return { users, posts };
}

// Parallèle (rapide)
async function getDataParallel() {
  const [users, posts] = await Promise.all([
    fetch('/api/users').then(r => r.json()),
    fetch('/api/posts').then(r => r.json())
  ]);
  return { users, posts };
}

Modules ES6 : organiser ton code

Les modules ES6 permettent de diviser ton code en fichiers réutilisables.

Export et Import

// utils.js
export const PI = 3.14159;

export function addition(a, b) {
  return a + b;
}

export class User {
  constructor(nom) {
    this.nom = nom;
  }
}

// Export par défaut (un seul par fichier)
export default function multiply(a, b) {
  return a * b;
}
// main.js
// Import nommé
import { PI, addition, User } from './utils.js';

// Import par défaut
import multiply from './utils.js';

// Import tout
import * as Utils from './utils.js';

console.log(Utils.PI); // 3.14159

Import dynamique

// Charger un module à la demande
async function loadModule() {
  const module = await import('./utils.js');
  console.log(module.PI);
}

Classes ES6 : la POO en JavaScript

Les classes simplifient la programmation orientée objet en JavaScript.

class Personne {
  // Constructeur
  constructor(nom, age) {
    this.nom = nom;
    this.age = age;
  }

  // Méthode
  sePresenter() {
    return `Je m'appelle ${this.nom} et j'ai ${this.age} ans`;
  }

  // Getter
  get infos() {
    return `${this.nom}, ${this.age} ans`;
  }

  // Setter
  set nouveauNom(nom) {
    this.nom = nom;
  }

  // Méthode statique
  static espece() {
    return 'Humain';
  }
}

const alex = new Personne('Alexandre', 28);
console.log(alex.sePresenter()); // "Je m'appelle Alexandre et j'ai 28 ans"
console.log(Personne.espece()); // "Humain"

Héritage avec extends

class Developpeur extends Personne {
  constructor(nom, age, langage) {
    super(nom, age); // Appelle le constructeur parent
    this.langage = langage;
  }

  coder() {
    return `${this.nom} code en ${this.langage}`;
  }
}

const dev = new Developpeur('Marie', 25, 'JavaScript');
console.log(dev.sePresenter()); // Méthode héritée
console.log(dev.coder()); // "Marie code en JavaScript"

Projet pratique : TODO List interactive

Mettons tout en pratique avec une vraie TODO list !

HTML

<div class="container">
  <h1>Ma TODO List</h1>
  <input type="text" id="taskInput" placeholder="Nouvelle tâche...">
  <button id="addBtn">Ajouter</button>
  <ul id="taskList"></ul>
</div>

JavaScript moderne

class TodoApp {
  constructor() {
    this.tasks = [];
    this.input = document.querySelector('#taskInput');
    this.addBtn = document.querySelector('#addBtn');
    this.taskList = document.querySelector('#taskList');

    this.init();
  }

  init() {
    this.addBtn.addEventListener('click', () => this.addTask());
    this.input.addEventListener('keypress', (e) => {
      if (e.key === 'Enter') this.addTask();
    });
  }

  addTask() {
    const text = this.input.value.trim();
    if (!text) return;

    const task = {
      id: Date.now(),
      text,
      completed: false
    };

    this.tasks.push(task);
    this.render();
    this.input.value = '';
  }

  deleteTask(id) {
    this.tasks = this.tasks.filter(task => task.id !== id);
    this.render();
  }

  toggleTask(id) {
    const task = this.tasks.find(t => t.id === id);
    if (task) task.completed = !task.completed;
    this.render();
  }

  render() {
    this.taskList.innerHTML = this.tasks
      .map(task => `
        <li class="${task.completed ? 'completed' : ''}">
          <input
            type="checkbox"
            ${task.completed ? 'checked' : ''}
            onchange="app.toggleTask(${task.id})"
          >
          <span>${task.text}</span>
          <button onclick="app.deleteTask(${task.id})">✕</button>
        </li>
      `)
      .join('');
  }
}

const app = new TodoApp();

🎉 En quelques lignes de JavaScript moderne, tu as une TODO list complète avec classes, arrow functions, template literals et destructuring !


Les pièges à éviter

  • Utiliser var : Toujours préférer let/const
  • Oublier async avec await : await ne fonctionne qu'avec async
  • Modifier un tableau/objet dans map/filter : Ces méthodes doivent être pures
  • Ne pas gérer les erreurs : Toujours un try/catch avec async/await
  • Confondre == et === : Toujours utiliser ===
  • Oublier le return : Les arrow functions sans accolades ont un return implicite

Les outils indispensables

  • 💻 VS Code : L'éditeur parfait pour JavaScript
  • 🔍 Chrome DevTools : Console, debugger, profiler
  • 📦 Node.js : Pour exécuter JS hors du navigateur
  • 🎨 Prettier : Formateur de code automatique
  • ESLint : Détecte les erreurs et bad practices
  • 🌐 Babel : Transpile ES6+ vers ES5 pour anciens navigateurs

Ressources pour progresser

  • 📖 MDN Web Docs : LA référence JavaScript
  • 🎓 javascript.info : Tutoriel complet et moderne
  • 💡 FreeCodeCamp : Exercices interactifs gratuits
  • 🎬 YouTube : Traversy Media, Fireship, Grafikart (FR)
  • 📚 You Don't Know JS : Série de livres gratuits
  • 🧪 CodeWars : Défis de code pour s'entraîner

Et maintenant ? Les prochaines étapes

Tu maîtrises maintenant JavaScript moderne ! Voici comment progresser :

  1. Pratique, pratique, pratique : Crée des projets (calculatrice, jeu, API)
  2. Apprends le DOM : Manipuler les éléments HTML avec JS
  3. Fetch API : Appels API et manipulation de données
  4. Local Storage : Sauvegarder des données dans le navigateur
  5. Frameworks modernes : React, Vue ou Angular
  6. Node.js : JavaScript côté serveur
  7. TypeScript : JavaScript avec des types

Consulte nos guides dédiés : React, Angular, et Node.js + TypeScript.


Conclusion

JavaScript moderne (ES6+) a révolutionné le développement web. Avec let/const, arrow functions, destructuring, promesses, async/await et modules, tu as tous les outils pour créer des applications web puissantes et maintenables.

Le plus important ? Pratique quotidiennement. Commence par des petits projets (calculatrice, quiz, timer), puis monte progressivement en complexité. Chaque ligne de code que tu écris te rapproche de la maîtrise.

JavaScript est un langage vivant qui évolue chaque année. Reste curieux, expérimente, casse des trucs, et surtout : amuse-toi ! Le code doit rester un plaisir. Bienvenue dans le monde merveilleux du JavaScript moderne ! 🚀✨