🔤 Les Bases de JavaScript
1.1 Variables et Types de Données
JavaScript est un langage dynamiquement typé. Voici les différentes façons de déclarer des variables :
// ES6+ - Préférées
let nom = "Alice"; // Variable modifiable
const age = 25; // Constante
const fruits = ["pomme", "banane"]; // Array constant (contenu modifiable)
// ES5 - À éviter
var ancienneVariable = "deprecated";
// Types primitifs
let nombre = 42; // Number
let texte = "Hello World"; // String
let booleen = true; // Boolean
let vide = null; // Null
let indefini; // Undefined
let symbole = Symbol("id"); // Symbol (ES6)
let bigint = 123n; // BigInt (ES2020)
console.log(typeof nombre); // "number"
🧪 Testez les variables :
1.2 Fonctions
Les fonctions sont des blocs de code réutilisables. JavaScript offre plusieurs syntaxes :
// Déclaration classique
function saluer(nom) {
return `Bonjour ${nom}!`;
}
// Expression de fonction
const direAuRevoir = function(nom) {
return `Au revoir ${nom}!`;
};
// Fonction fléchée (ES6)
const calculer = (a, b) => a + b;
const carre = x => x * x; // Un seul paramètre
const direBonjour = () => "Bonjour!"; // Pas de paramètre
// Fonction avec paramètres par défaut
const presenter = (nom = "Anonyme", age = 0) => {
return `Je suis ${nom}, j'ai ${age} ans`;
};
// Rest parameters
const additionner = (...nombres) => {
return nombres.reduce((sum, num) => sum + num, 0);
};
console.log(additionner(1, 2, 3, 4)); // 10
🧪 Calculatrice Interactive :
1.3 Structures de Contrôle
Conditions, boucles et gestion des flux :
// Conditions
const age = 18;
if (age >= 18) {
console.log("Majeur");
} else if (age >= 13) {
console.log("Adolescent");
} else {
console.log("Enfant");
}
// Ternaire
const statut = age >= 18 ? "Majeur" : "Mineur";
// Switch
const jour = "lundi";
switch (jour) {
case "lundi":
case "mardi":
console.log("Début de semaine");
break;
case "vendredi":
console.log("TGIF!");
break;
default:
console.log("Jour ordinaire");
}
// Boucles
for (let i = 0; i < 5; i++) {
console.log(`Itération ${i}`);
}
// For...of (arrays)
const couleurs = ["rouge", "vert", "bleu"];
for (const couleur of couleurs) {
console.log(couleur);
}
// For...in (objets)
const personne = { nom: "Alice", age: 30 };
for (const cle in personne) {
console.log(`${cle}: ${personne[cle]}`);
}
🧪 Générateur de Table de Multiplication :
🌐 Manipulation du DOM
2.1 Sélection d'Éléments
Le DOM (Document Object Model) représente la structure HTML de votre page :
// Sélection par ID
const titre = document.getElementById('mon-titre');
// Sélection par classe (premier élément)
const premiereBouton = document.querySelector('.bouton');
// Sélection par classe (tous les éléments)
const tousBoutons = document.querySelectorAll('.bouton');
// Sélection par tag
const paragraphes = document.getElementsByTagName('p');
// Sélecteurs CSS avancés
const premierP = document.querySelector('div > p:first-child');
const liens = document.querySelectorAll('a[href^="https"]');
// Navigation dans le DOM
const parent = element.parentNode;
const enfants = element.children;
const suivant = element.nextElementSibling;
🧪 Sélecteur Interactif :
Titre de Démo
Paragraphe 1
Paragraphe 2 (spécial)
2.2 Modification du Contenu
Changez dynamiquement le contenu et les styles :
// Modifier le texte
element.textContent = "Nouveau texte";
element.innerHTML = "Texte en gras";
// Modifier les attributs
element.setAttribute('class', 'nouvelle-classe');
element.id = 'nouvel-id';
element.style.color = 'blue';
element.style.backgroundColor = '#f0f0f0';
// Ajouter/supprimer des classes
element.classList.add('active');
element.classList.remove('hidden');
element.classList.toggle('visible');
element.classList.contains('special'); // true/false
// Créer de nouveaux éléments
const nouveauDiv = document.createElement('div');
nouveauDiv.textContent = 'Nouveau contenu';
document.body.appendChild(nouveauDiv);
// Supprimer un élément
element.remove();
// ou
parent.removeChild(element);
🧪 Éditeur de Style en Direct :
Élément à Styliser
Modifiez-moi avec les contrôles ci-dessous !
2.3 Gestion des Événements
Réagissez aux interactions utilisateur :
// Événements de base
button.addEventListener('click', function() {
console.log('Bouton cliqué !');
});
// Fonction fléchée
button.addEventListener('click', () => {
console.log('Clic avec arrow function');
});
// Avec paramètre event
input.addEventListener('input', (event) => {
console.log('Valeur:', event.target.value);
});
// Événements de formulaire
form.addEventListener('submit', (e) => {
e.preventDefault(); // Empêcher l'envoi par défaut
const formData = new FormData(form);
console.log('Données:', Object.fromEntries(formData));
});
// Événements de souris
element.addEventListener('mouseenter', () => console.log('Souris entrée'));
element.addEventListener('mouseleave', () => console.log('Souris sortie'));
// Événements de clavier
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
console.log('Échap pressé');
}
});
// Supprimer un événement
const clickHandler = () => console.log('Click');
button.addEventListener('click', clickHandler);
button.removeEventListener('click', clickHandler);
🧪 Détecteur d'Événements :
⚡ Programmation Asynchrone
3.1 Promises
Les Promises permettent de gérer les opérations asynchrones :
// Créer une Promise
const maPromise = new Promise((resolve, reject) => {
const succes = true;
setTimeout(() => {
if (succes) {
resolve("Opération réussie !");
} else {
reject("Erreur survenue !");
}
}, 2000);
});
// Utiliser la Promise
maPromise
.then(resultat => {
console.log(resultat);
return "Données traitées";
})
.then(donnees => {
console.log(donnees);
})
.catch(erreur => {
console.error(erreur);
})
.finally(() => {
console.log("Terminé");
});
// Promise.all - Attendre plusieurs promises
const promise1 = fetch('/api/user');
const promise2 = fetch('/api/posts');
Promise.all([promise1, promise2])
.then(responses => {
console.log('Toutes les requêtes terminées');
});
// Promise.race - Première promise résolue
Promise.race([promise1, promise2])
.then(firstResponse => {
console.log('Première réponse:', firstResponse);
});
🧪 Simulateur de Promises :
3.2 Async/Await
Syntaxe moderne pour les opérations asynchrones :
// Fonction async basique
async function obtenirDonnees() {
try {
const response = await fetch('/api/data');
const data = await response.json();
return data;
} catch (error) {
console.error('Erreur:', error);
throw error;
}
}
// Arrow function async
const chargerUtilisateur = async (id) => {
const user = await fetch(`/api/users/${id}`);
return await user.json();
};
// Utilisation
async function main() {
try {
const donnees = await obtenirDonnees();
console.log(donnees);
const utilisateur = await chargerUtilisateur(1);
console.log(utilisateur);
} catch (error) {
console.error('Erreur dans main:', error);
}
}
// Attendre plusieurs opérations
async function chargerTout() {
const [users, posts, comments] = await Promise.all([
fetch('/api/users').then(r => r.json()),
fetch('/api/posts').then(r => r.json()),
fetch('/api/comments').then(r => r.json())
]);
return { users, posts, comments };
}
🧪 API Simulator :
3.3 Fetch API
Interface moderne pour les requêtes HTTP :
// GET request basique
const obtenirDonnees = async () => {
const response = await fetch('https://api.exemple.com/data');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
};
// POST request avec données
const creerUtilisateur = async (userData) => {
const response = await fetch('/api/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(userData)
});
return await response.json();
};
// Requête avec authentification
const donneesPrivees = async (token) => {
const response = await fetch('/api/private', {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
return await response.json();
};
// Upload de fichier
const uploaderFichier = async (file) => {
const formData = new FormData();
formData.append('file', file);
const response = await fetch('/api/upload', {
method: 'POST',
body: formData
});
return await response.json();
};
🆕 Fonctionnalités ES6+
4.1 Destructuring et Spread
Syntaxes modernes pour extraire et combiner des données :
// Destructuring d'objets
const personne = { nom: "Alice", age: 30, ville: "Paris" };
const { nom, age, ville = "Non spécifiée" } = personne;
const { nom: prenomAlias } = personne; // Renommer
// Destructuring d'arrays
const couleurs = ["rouge", "vert", "bleu"];
const [premiere, deuxieme, ...autres] = couleurs;
// Destructuring dans les paramètres
const saluer = ({ nom, age }) => {
return `Bonjour ${nom}, vous avez ${age} ans`;
};
// Spread operator avec objets
const infosBase = { nom: "Bob", age: 25 };
const infosCompletes = {
...infosBase,
ville: "Lyon",
age: 26 // Override
};
// Spread avec arrays
const nombres1 = [1, 2, 3];
const nombres2 = [4, 5, 6];
const tousNombres = [...nombres1, ...nombres2];
// Rest parameters
const calculer = (operation, ...nombres) => {
switch(operation) {
case 'sum':
return nombres.reduce((a, b) => a + b, 0);
case 'multiply':
return nombres.reduce((a, b) => a * b, 1);
default:
return 0;
}
};
🧪 Destructuring Playground :
Objet à destructurer :
Pattern de destructuring :
4.2 Template Literals
Chaînes de caractères avec interpolation :
// Template literals basiques
const nom = "Alice";
const age = 30;
const message = `Bonjour ${nom}, vous avez ${age} ans`;
// Multilignes
const html = `
${nom}
Âge: ${age}
Statut: ${age >= 18 ? 'Majeur' : 'Mineur'}
`;
// Expressions dans les templates
const prix = 19.99;
const tva = 0.20;
const facture = `
Prix HT: ${prix.toFixed(2)}€
TVA: ${(prix * tva).toFixed(2)}€
Total: ${(prix * (1 + tva)).toFixed(2)}€
`;
// Tagged templates (avancé)
function highlight(strings, ...values) {
return strings.reduce((result, string, i) => {
const value = values[i] ? `${values[i]}` : '';
return result + string + value;
}, '');
}
const recherche = "JavaScript";
const texte = highlight`Apprendre ${recherche} est passionnant !`;
🧪 Générateur de Templates :
4.3 Modules ES6
Import/Export pour organiser le code :
// math.js - Exports nommés
export const PI = 3.14159;
export const E = 2.71828;
export function add(a, b) {
return a + b;
}
export const multiply = (a, b) => a * b;
// Export par défaut
export default function subtract(a, b) {
return a - b;
}
// utils.js - Export d'objet
const utils = {
formatDate: (date) => date.toISOString(),
randomId: () => Math.random().toString(36).substr(2, 9),
capitalize: (str) => str.charAt(0).toUpperCase() + str.slice(1)
};
export default utils;
// main.js - Imports
import subtract, { PI, add, multiply } from './math.js';
import utils from './utils.js';
import * as mathModule from './math.js'; // Import tout
// Utilisation
console.log(add(2, 3));
console.log(PI);
console.log(utils.randomId());
console.log(mathModule.E);
// Import dynamique
async function loadModule() {
const { default: dynamicUtils } = await import('./utils.js');
return dynamicUtils;
}
🧩 Programmation Orientée Objet
5.1 Classes ES6
Syntaxe moderne pour créer des objets :
// Classe basique
class Personne {
constructor(nom, age) {
this.nom = nom;
this.age = age;
this._id = Math.random().toString(36); // Propriété "privée"
}
// Méthode
saluer() {
return `Bonjour, je suis ${this.nom}`;
}
// Getter
get infos() {
return `${this.nom} (${this.age} ans)`;
}
// Setter
set nouveauNom(nom) {
if (nom.length > 0) {
this.nom = nom;
}
}
// Méthode statique
static creerBebe(nom) {
return new Personne(nom, 0);
}
}
// Héritage
class Developpeur extends Personne {
constructor(nom, age, langage) {
super(nom, age); // Appel du constructeur parent
this.langage = langage;
this.projets = [];
}
// Override de méthode
saluer() {
return `${super.saluer()}, je développe en ${this.langage}`;
}
ajouterProjet(projet) {
this.projets.push(projet);
}
// Propriétés privées (ES2022)
#motDePasse = "secret";
#verifierAcces() {
return this.#motDePasse === "secret";
}
}
// Utilisation
const alice = new Developpeur("Alice", 28, "JavaScript");
console.log(alice.saluer());
alice.ajouterProjet("Site Web");
console.log(alice.projets);
🧪 Constructeur de Classes :
5.2 Prototypes
Système de prototypes JavaScript :
// Fonction constructeur
function Animal(nom, type) {
this.nom = nom;
this.type = type;
}
// Ajouter des méthodes au prototype
Animal.prototype.parler = function() {
return `${this.nom} fait du bruit`;
};
Animal.prototype.dormir = function() {
return `${this.nom} dort`;
};
// Héritage avec prototype
function Chien(nom, race) {
Animal.call(this, nom, 'chien'); // Super constructor
this.race = race;
}
// Configurer l'héritage
Chien.prototype = Object.create(Animal.prototype);
Chien.prototype.constructor = Chien;
// Override de méthode
Chien.prototype.parler = function() {
return `${this.nom} aboie : Woof!`;
};
// Nouvelle méthode
Chien.prototype.chercher = function() {
return `${this.nom} court chercher la balle`;
};
// Utilisation
const rex = new Chien("Rex", "Golden Retriever");
console.log(rex.parler()); // Rex aboie : Woof!
console.log(rex.dormir()); // Rex dort (hérité)
// Vérifications
console.log(rex instanceof Chien); // true
console.log(rex instanceof Animal); // true
🚀 Concepts Avancés
6.1 Closures et Scopes
Compréhension des portées et fermetures :
// Closure basique
function creerCompteur() {
let count = 0;
return function() {
count++;
return count;
};
}
const compteur1 = creerCompteur();
const compteur2 = creerCompteur();
console.log(compteur1()); // 1
console.log(compteur1()); // 2
console.log(compteur2()); // 1 (instance séparée)
// Module pattern
const calculatrice = (function() {
let historique = [];
return {
add: function(a, b) {
const result = a + b;
historique.push(`${a} + ${b} = ${result}`);
return result;
},
getHistorique: function() {
return [...historique]; // Copie pour éviter la mutation
},
clear: function() {
historique = [];
}
};
})();
// Factory function avec closure
function creerPersonne(nom) {
let age = 0;
let secrets = [];
return {
getNom: () => nom,
getAge: () => age,
vieillir: () => ++age,
ajouterSecret: (secret) => secrets.push(secret),
getNbSecrets: () => secrets.length
// secrets reste privé !
};
}
🧪 Démonstration des Closures :
6.2 Higher-Order Functions
Fonctions qui opèrent sur d'autres fonctions :
// Map, Filter, Reduce
const nombres = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Map - transformation
const carres = nombres.map(n => n * n);
const doubles = nombres.map(n => n * 2);
// Filter - filtrage
const pairs = nombres.filter(n => n % 2 === 0);
const grands = nombres.filter(n => n > 5);
// Reduce - accumulation
const somme = nombres.reduce((acc, n) => acc + n, 0);
const max = nombres.reduce((max, n) => n > max ? n : max, 0);
// Chaînage
const resultat = nombres
.filter(n => n % 2 === 0) // Pairs seulement
.map(n => n * n) // Au carré
.reduce((acc, n) => acc + n, 0); // Somme
// Fonctions custom
const users = [
{ nom: "Alice", age: 25, actif: true },
{ nom: "Bob", age: 30, actif: false },
{ nom: "Charlie", age: 35, actif: true }
];
// Find
const alice = users.find(user => user.nom === "Alice");
// Some/Every
const aDesActifs = users.some(user => user.actif);
const tousActifs = users.every(user => user.actif);
// Sort
const parAge = users.sort((a, b) => a.age - b.age);
// Fonction qui retourne une fonction
const creerFiltre = (propriete, valeur) => {
return obj => obj[propriete] === valeur;
};
const filtrerParAge30 = creerFiltre('age', 30);
const utilisateurs30 = users.filter(filtrerParAge30);
🧪 Array Methods Explorer :
6.3 Regular Expressions
Expressions régulières pour manipuler du texte :
// Création de regex
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
const phoneRegex = new RegExp(r'\d{2}-\d{2}-\d{2}-\d{2}-\d{2}');
// Test basique
const email = "alice@exemple.com";
console.log(emailRegex.test(email)); // true
// Recherche et extraction
const texte = "Appelez-moi au 01-23-45-67-89 ou 06-98-76-54-32";
const telephones = texte.match(/\d{2}-\d{2}-\d{2}-\d{2}-\d{2}/g);
console.log(telephones); // ["01-23-45-67-89", "06-98-76-54-32"]
// Remplacement
const texteNettoye = texte.replace(/\d{2}-\d{2}-\d{2}-\d{2}-\d{2}/g, "[TÉLÉPHONE]");
// Groupes de capture
const urlRegex = /https?:\/\/([^\/]+)(\/.*)?/;
const url = "https://exemple.com/page?param=value";
const [, domaine, chemin] = url.match(urlRegex);
// Validation complexe
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
function validerMotDePasse(mdp) {
return {
valide: passwordRegex.test(mdp),
longueur: mdp.length >= 8,
minuscule: /[a-z]/.test(mdp),
majuscule: /[A-Z]/.test(mdp),
chiffre: /\d/.test(mdp),
special: /[@$!%*?&]/.test(mdp)
};
}
// Split avancé
const csv = "nom,age,ville\nAlice,25,Paris\nBob,30,Lyon";
const lignes = csv.split(/\r?\n/);
const donnees = lignes.slice(1).map(ligne => ligne.split(','));
🧪 RegExp Testeur :
💼 Projets Pratiques
🛒 Projet 1 : Liste de Courses Interactive
Application complète avec localStorage :
class ShoppingList {
constructor() {
this.items = this.loadFromStorage();
this.render();
}
addItem(text) {
if (text.trim()) {
const item = {
id: Date.now(),
text: text.trim(),
completed: false
};
this.items.push(item);
this.saveToStorage();
this.render();
}
}
toggleItem(id) {
const item = this.items.find(item => item.id === id);
if (item) {
item.completed = !item.completed;
this.saveToStorage();
this.render();
}
}
deleteItem(id) {
this.items = this.items.filter(item => item.id !== id);
this.saveToStorage();
this.render();
}
saveToStorage() {
localStorage.setItem('shoppingList', JSON.stringify(this.items));
}
loadFromStorage() {
const stored = localStorage.getItem('shoppingList');
return stored ? JSON.parse(stored) : [];
}
}
🎮 Projet 2 : Jeu de Mémoire
Jeu interactif avec gestion d'état :
📊 Projet 3 : Calculatrice Avancée
Calculatrice avec historique et fonctions scientifiques :