Loading repository data…
Loading repository data…
GasyCoder / repository
Auteur : Support de cours universitaire - BEZARA Florent Niveau : Licence 3 — Informatique Prérequis : Bases solides en HTML, CSS, JavaScript (ES6+), notions de programmation orientée objet Volume horaire indicatif : 40 à 50 heures (cours + TP)
Le développement web a profondément évolué depuis les premières pages HTML statiques des années 1990. Aujourd'hui, les applications web sont devenues aussi complexes et riches que les applications de bureau traditionnelles. Des services comme Gmail, Trello, Spotify ou Netflix sont des applications web à part entière, offrant des interfaces interactives et réactives.
Cette évolution a été rendue possible grâce à un langage de programmation : JavaScript. Initialement conçu en 1995 par Brendan Eich pour ajouter de l'interactivité aux pages web dans le navigateur Netscape, JavaScript est devenu le langage le plus utilisé au monde. Sa particularité unique est de fonctionner à la fois côté client (dans le navigateur) et côté serveur (grâce à Node.js), ce qui permet de construire des applications complètes avec un seul langage.
Cependant, écrire des applications complexes en JavaScript pur (dit « vanilla ») devient rapidement ingérable : le code devient difficile à organiser, à maintenir et à faire évoluer. C'est précisément pour répondre à ce problème que les frameworks et bibliothèques JavaScript ont été créés.
À l'issue de ce cours, vous serez capable de :
Le cours est organisé en trois grandes parties qui suivent une progression logique :
Avant d'aborder les frameworks, il est indispensable de maîtriser les fonctionnalités modernes de JavaScript introduites depuis ECMAScript 2015 (ES6). Ces fonctionnalités sont massivement utilisées dans tous les frameworks.
let et constAvant ES6, on utilisait uniquement var pour déclarer des variables. Désormais, on préfère let et const qui offrent une portée de bloc (block scope) plus prévisible.
// var a une portée de fonction (function scope) — à éviter
var nom = "Alice";
// let a une portée de bloc — utilisable quand la valeur change
let age = 25;
age = 26; // OK : réassignation autorisée
// const a une portée de bloc — la référence ne peut pas être réassignée
const PI = 3.14159;
// PI = 3.14; // ERREUR : réassignation impossible
// Attention : const ne rend pas l'objet immuable
const etudiant = { nom: "Bob", age: 22 };
etudiant.age = 23; // OK : on modifie une propriété, pas la référence
Règle pratique : Utilisez toujours const par défaut. N'utilisez let que lorsque vous avez réellement besoin de réassigner la variable. N'utilisez jamais var dans du code moderne.
Les fonctions fléchées offrent une syntaxe plus concise et un comportement spécifique du mot-clé this (il conserve le this du contexte englobant).
// Fonction classique
function addition(a, b) {
return a + b;
}
// Fonction fléchée — forme complète
const addition = (a, b) => {
return a + b;
};
// Fonction fléchée — forme raccourcie (retour implicite)
const addition = (a, b) => a + b;
// Avec un seul paramètre, les parenthèses sont optionnelles
const doubler = x => x * 2;
// Utilisation courante avec les méthodes de tableau
const nombres = [1, 2, 3, 4, 5];
const pairs = nombres.filter(n => n % 2 === 0); // [2, 4]
const doubles = nombres.map(n => n * 2); // [2, 4, 6, 8, 10]
const somme = nombres.reduce((acc, n) => acc + n, 0); // 15
La déstructuration permet d'extraire des valeurs d'objets ou de tableaux de manière élégante.
// Déstructuration d'objet
const etudiant = {
nom: "Alice",
age: 22,
filiere: "Informatique",
universite: "Université de Mahajanga"
};
// Au lieu de : const nom = etudiant.nom; const age = etudiant.age;
const { nom, age, filiere } = etudiant;
console.log(nom); // "Alice"
console.log(filiere); // "Informatique"
// Renommage lors de la déstructuration
const { nom: nomEtudiant, age: ageEtudiant } = etudiant;
// Valeur par défaut
const { note = 0 } = etudiant; // note vaudra 0 car elle n'existe pas
// Déstructuration de tableau
const couleurs = ["rouge", "vert", "bleu"];
const [premiere, deuxieme, troisieme] = couleurs;
console.log(premiere); // "rouge"
// Ignorer des éléments
const [, , derniere] = couleurs;
console.log(derniere); // "bleu"
...) et restL'opérateur ... (trois points) sert à deux choses selon le contexte.
// SPREAD : « étaler » les éléments d'un tableau ou d'un objet
// Copie superficielle d'un tableau
const original = [1, 2, 3];
const copie = [...original]; // [1, 2, 3]
const etendu = [...original, 4, 5]; // [1, 2, 3, 4, 5]
// Fusion de tableaux
const a = [1, 2];
const b = [3, 4];
const fusion = [...a, ...b]; // [1, 2, 3, 4]
// Copie et modification d'objets (très utilisé dans React et Vue)
const config = { theme: "dark", langue: "fr" };
const nouvelleConfig = { ...config, langue: "en" };
// { theme: "dark", langue: "en" }
// REST : collecter le « reste » des arguments
function journaliser(premier, ...autres) {
console.log("Premier :", premier);
console.log("Autres :", autres);
}
journaliser("A", "B", "C", "D");
// Premier : A
// Autres : ["B", "C", "D"]
const nom = "Alice";
const age = 22;
// Avant ES6
const message = "Bonjour, je suis " + nom + " et j'ai " + age + " ans.";
// Avec les template literals (backticks `)
const message = `Bonjour, je suis ${nom} et j'ai ${age} ans.`;
// Multiligne
const html = `
<div class="carte">
<h2>${nom}</h2>
<p>Âge : ${age}</p>
</div>
`;
// Expressions dans les interpolations
const prix = 1500;
const tva = 0.2;
console.log(`Prix TTC : ${prix * (1 + tva)} Ar`); // "Prix TTC : 1800 Ar"
Les modules permettent de découper le code en fichiers distincts et réutilisables. C'est le fondement de l'architecture de tout framework.
// ===== fichier : mathUtils.js =====
// Export nommé (on peut en avoir plusieurs par fichier)
export const PI = 3.14159;
export function carre(x) {
return x * x;
}
export function cube(x) {
return x * x * x;
}
// Export par défaut (un seul par fichier)
export default function addition(a, b) {
return a + b;
}
// ===== fichier : main.js =====
// Import de l'export par défaut
import addition from './mathUtils.js';
// Import des exports nommés
import { PI, carre, cube } from './mathUtils.js';
// Import combiné
import addition, { PI, carre } from './mathUtils.js';
// Import avec alias
import { carre as carreDeNombre } from './mathUtils.js';
console.log(addition(3, 4)); // 7
console.log(carre(5)); // 25
console.log(PI); // 3.14159
JavaScript est asynchrone par nature. Les Promesses et async/await permettent de gérer les opérations qui prennent du temps (appels réseau, lecture de fichiers) sans bloquer l'exécution du programme.
// Une Promesse représente une valeur qui sera disponible dans le futur
// Création d'une Promesse
const maPromesse = new Promise((resolve, reject) => {
const succes = true;
setTimeout(() => {
if (succes) {
resolve("Opération réussie !");
} else {
reject("Erreur : opération échouée.");
}
}, 2000); // Simule un délai de 2 secondes
});
// Consommation avec .then() et .catch()
maPromesse
.then(resultat => console.log(resultat)) // "Opération réussie !"
.catch(erreur => console.error(erreur));
// Syntaxe async/await — plus lisible (syntaxe recommandée)
async function recupererDonnees() {
try {
const reponse = await fetch('https://api.exemple.com/etudiants');
if (!reponse.ok) {
throw new Error(`Erreur HTTP : ${reponse.status}`);
}
const donnees = await reponse.json();
console.log(donnees);
return donnees;
} catch (erreur) {
console.error("Erreur lors de la récupération :", erreur.message);
}
}
// Appel de la fonction asynchrone
recupererDonnees();
Point clé : await ne peut être utilisé que dans une fonction déclarée avec async. Il « met en pause » l'exécution de la fonction jusqu'à ce que la Promesse soit résolue, mais il ne bloque pas le reste du programme.
Ces méthodes sont omniprésentes dans les frameworks pour manipuler et afficher des données.
const etudiants = [
{ nom: "Alice", note: 16, filiere: "Info" },
{ nom: "Bob", note: 12, filiere: "Math" },
{ nom: "Charlie", note: 18, filiere: "Info" },
{ nom: "Diana", note: 9, filiere: "Info" },
{ nom: "Eve", note: 14, filiere: "Math" },
];
// map() — Transforme chaque élément et retourne un nouveau tableau
const noms = etudiants.map(e => e.nom);
// ["Alice", "Bob", "Charlie", "Diana", "Eve"]
// filter() — Garde uniquement les éléments qui satisfont la condition
const bonsEtudiants = etudiants.filter(e => e.note >= 14);
// [{ nom: "Alice", ... }, { nom: "Charlie", ... }, { no