Le jargon technique complet en JavaScript
Concepts fondamentaux étendus
Opérateurs et expressions
Opérateurs d'égalité
== : égalité avec conversion de type
=== : égalité stricte (valeur et type)
!= : inégalité avec conversion
!== : inégalité stricte
javascript
// Toujours préférer === pour éviter les erreurs de conversion
5 === "5" // false
5 == "5" // true (conversion implicite)
Opérateurs logiques
&& : ET logique (court-circuit)
|| : OU logique (court-circuit)
! : NON logique
?? : coalescence des nuls
javascript
// && est souvent utilisé pour l'exécution conditionnelle
isAdmin && executerFonctionAdmin();
// || est utilisé pour les valeurs par défaut (attention aux falsy values)
const nom = inputNom || "Anonyme";
// ?? est préférable quand seuls null/undefined doivent être évités
const quantite = valeurEntrée ?? 0; // 0, "", false sont préservés
Types de données avancés
WeakMap et WeakSet
Collections qui permettent la collecte de garbage
javascript
const weakMap = new WeakMap();
let obj = {data: "valeur"};
weakMap.set(obj, "métadonnées");
// Si obj est supprimé, weakMap libère automatiquement sa référence
TypedArray
Arrays à type fixe pour les performances
javascript
const buffer = new ArrayBuffer(16);
const int32View = new Int32Array(buffer);
Symbols
Identifiants uniques, souvent utilisés comme clés d'objet
javascript
const ID = Symbol("id");
const objet = {
[ID]: "valeur unique"
};
Prototypes et chaîne de prototypes
Prototype
Mécanisme d'héritage en JavaScript
javascript
function Personne(nom) {
this.nom = nom;
}
Personne.prototype.saluer = function() {
return `Bonjour, je suis ${this.nom}`;
};
const alice = new Personne("Alice");
Object.create()
Crée un objet avec un prototype spécifié
javascript
const personnePrototype = {
saluer() {
return `Bonjour, je suis ${this.nom}`;
}
};
const alice = Object.create(personnePrototype);
alice.nom = "Alice";
Manipulation du DOM approfondie
API Modernes du DOM
querySelector et querySelectorAll
Sélection d'éléments avec sélecteurs CSS
javascript
// Un seul élément
const header = document.querySelector("header");
// Tous les éléments correspondants
const paragraphes = document.querySelectorAll("p.important");
Méthodes de traversée
closest() : trouve l'ancêtre correspondant
matches() : vérifie si un élément correspond à un sélecteur
javascript
const enfant = document.querySelector(".enfant");
const parent = enfant.closest(".parent");
if (element.matches(".classe")) {
// L'élément a la classe spécifiée
}
Manipulation de classes
classList : interface pour gérer les classes CSS
javascript
element.classList.add("active");
element.classList.remove("inactive");
element.classList.toggle("visible");
element.classList.replace("old", "new");
Web APIs
Intersection Observer
Détecte quand un élément entre dans le viewport
javascript
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add("visible");
}
});
});
observer.observe(document.querySelector(".element-a-observer"));
MutationObserver
Observe les changements dans le DOM
javascript
const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
console.log("DOM modifié:", mutation);
});
});
observer.observe(element, { childList: true, subtree: true });
ResizeObserver
Détecte les changements de taille d'un élément
javascript
const observer = new ResizeObserver(entries => {
for (const entry of entries) {
console.log("Élément redimensionné:", entry.contentRect);
}
});
observer.observe(document.querySelector(".conteneur"));
Programmation asynchrone avancée
Promise API complète
Promise.all()
Attend que toutes les promesses soient résolues
javascript
const promesses = [fetch("/api/1"), fetch("/api/2"), fetch("/api/3")];
Promise.all(promesses)
.then(resultats => {
console.log("Toutes les requêtes terminées");
})
.catch(erreur => {
console.error("Au moins une requête a échoué");
});
Promise.race()
Retourne la première promesse résolue ou rejetée
javascript
const timeout = new Promise((_, reject) => setTimeout(() => reject("Timeout"), 5000));
const donnees = fetch("/api/donnees");
Promise.race([donnees, timeout])
.then(result => console.log("Données obtenues à temps"))
.catch(err => console.error("Trop lent ou erreur:", err));
Promise.allSettled()
Attend que toutes les promesses soient soit résolues soit rejetées
javascript
Promise.allSettled([
fetch("/api/1"),
fetch("/api/2")
])
.then(resultats => {
resultats.forEach(resultat => {
if (resultat.status === "fulfilled") {
console.log("Réussi:", resultat.value);
} else {
console.log("Échoué:", resultat.reason);
}
});
});
Promise.any()
Retourne la première promesse résolue avec succès
javascript
Promise.any([
fetch("https://api1.example.com/data"),
fetch("https://api2.example.com/data"),
fetch("https://api3.example.com/data")
])
.then(premiereReponse => console.log("Première API qui répond:", premiereReponse))
.catch(erreur => console.log("Toutes les API ont échoué"));
Générateurs et itérateurs
Générateurs
Fonctions qui peuvent être suspendues et reprises
javascript
function* generatrice() {
yield 1;
yield 2;
yield 3;
}
const gen = generatrice();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
Itérateurs
Objets implémentant l'interface d'itération
javascript
const iterable = {
[Symbol.iterator]() {
let i = 0;
return {
next() {
return i < 5 ? { value: i++, done: false } : { done: true };
}
};
}
};
for (const valeur of iterable) {
console.log(valeur); // 0, 1, 2, 3, 4
}
Générateurs asynchrones
Générateurs qui produisent des promesses
javascript
async function* streamData() {
let i = 0;
while (i < 5) {
const response = await fetch(`/api/data/${i}`);
yield await response.json();
i++;
}
}
(async () => {
for await (const data of streamData()) {
console.log(data);
}
})();
API du navigateur et Web APIs
Storage API
localStorage et sessionStorage
Stockage de données côté client
javascript
// Persiste après fermeture du navigateur
localStorage.setItem("userPrefs", JSON.stringify({ theme: "dark" }));
const prefs = JSON.parse(localStorage.getItem("userPrefs"));
// Persiste uniquement pendant la session
sessionStorage.setItem("tempData", "valeur");
Service Workers
Enregistrement et utilisation
Scripts qui s'exécutent en arrière-plan
javascript
// Enregistrement
navigator.serviceWorker.register('/sw.js')
.then(registration => console.log('SW enregistré'))
.catch(error => console.log('Échec:', error));
// Dans sw.js
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => response || fetch(event.request))
);
});
WebSockets
Communication bidirectionnelle
Connexion persistante pour échange en temps réel
javascript
const ws = new WebSocket('wss://example.com/socket');
ws.onopen = () => {
console.log('Connexion établie');
ws.send('Hello server');
};
ws.onmessage = event => {
console.log('Message reçu:', event.data);
};
Fetch API avancée
Options avancées
Configuration des requêtes HTTP
javascript
fetch('/api/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({ name: 'Jean' }),
credentials: 'include', // Envoie les cookies
mode: 'cors',
cache: 'no-cache'
})
AbortController
Annulation des requêtes fetch
javascript
const controller = new AbortController();
const signal = controller.signal;
fetch('/api/data', { signal })
.then(response => response.json())
.catch(err => {
if (err.name === 'AbortError') {
console.log('Requête annulée');
}
});
// Pour annuler
setTimeout(() => controller.abort(), 5000);
JavaScript moderne (ES6+)
Fonctionnalités ES6+
Template Literals
Chaînes multilignes et interpolation
javascript
const nom = "Alice";
const message = `Bonjour ${nom},
Comment allez-vous aujourd'hui?`;
Paramètres par défaut
Valeurs par défaut pour les paramètres de fonction
javascript
function creerUtilisateur(nom, role = "utilisateur", actif = true) {
return { nom, role, actif };
}
Paramètres rest
Collecte les arguments restants dans un tableau
javascript
function somme(...nombres) {
return nombres.reduce((total, n) => total + n, 0);
}
console.log(somme(1, 2, 3, 4)); // 10
Optional chaining
Accès aux propriétés imbriquées sans erreur
javascript
const valeur = objet?.propriete?.sousPropriete;
Nullish coalescing vs OR
Différence subtile entre ?? et ||
javascript
// || considère 0, "", false comme "falsy"
0 || "défaut" // "défaut"
// ?? ne considère que null et undefined
0 ?? "défaut" // 0
Modules ECMAScript
Exports nommés et par défaut
Organisation du code avec exports multiples
javascript
// utils.js
export function formater(texte) { return texte.trim(); }
export function capitaliser(texte) { return texte.toUpperCase(); }
export default class Utilitaire { /* ... */ }
// app.js
import Utilitaire, { formater, capitaliser as majuscules } from './utils.js';
Import dynamique
Chargement à la demande des modules
javascript
async function chargerModule() {
if (condition) {
const module = await import('./module-conditionnel.js');
module.fonction();
}
}
Patrons de conception (Design Patterns)
Patrons créationnels
Factory
Crée des objets sans spécifier leur classe exacte
javascript
function creerUtilisateur(type) {
if (type === "admin") return new Admin();
if (type === "editeur") return new Editeur();
return new Utilisateur();
}
Singleton
Assure qu'une classe n'a qu'une seule instance
javascript
class Database {
static instance;
constructor() {
if (Database.instance) {
return Database.instance;
}
this.connexion = "connexion à la DB";
Database.instance = this;
}
}
const db1 = new Database();
const db2 = new Database();
console.log(db1 === db2); // true
Patrons structurels
Module
Encapsule des fonctionnalités
javascript
const monModule = (function() {
// Variables privées
let compteur = 0;
// Retourne l'API publique
return {
incrementer() {
compteur++;
return compteur;
},
getCompteur() {
return compteur;
}
};
})();
Observer
Communication par événements
javascript
class Sujet {
constructor() {
this.observateurs = [];
}
souscrire(observateur) {
this.observateurs.push(observateur);
}
notifier(data) {
this.observateurs.forEach(obs => obs.update(data));
}
}
class Observateur {
update(data) {
console.log("Données mises à jour:", data);
}
}
Techniques d'optimisation
Memoization
Mise en cache des résultats
Optimisation des fonctions coûteuses
javascript
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 calculCouteux = memoize(function(n) {
console.log("Calcul...");
return n * n;
});
Debounce et Throttle
Debounce
Limite l'exécution après un délai d'inactivité
javascript
function debounce(fn, delay) {
let timer;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
const rechercheDebounced = debounce(function(terme) {
console.log("Recherche:", terme);
}, 300);
// Usage: l'utilisateur tape rapidement
input.addEventListener("input", e => rechercheDebounced(e.target.value));
Throttle
Limite la fréquence d'exécution
javascript
function throttle(fn, limit) {
let estEnAttente = false;
return function(...args) {
if (!estEnAttente) {
fn.apply(this, args);
estEnAttente = true;
setTimeout(() => {
estEnAttente = false;
}, limit);
}
};
}
const scrollThrottled = throttle(() => {
console.log("Position scroll:", window.scrollY);
}, 100);
window.addEventListener("scroll", scrollThrottled);
Testing
Types de tests
Tests unitaires
Test de fonctions/composants isolés
javascript
// Avec Jest
test('additionne deux nombres', () => {
expect(additionner(1, 2)).toBe(3);
});
Tests d'intégration
Vérifie l'interaction entre composants
javascript
test('formulaire soumet les données correctement', async () => {
render(<Formulaire />);
fireEvent.change(screen.getByLabelText('Nom'), { target: { value: 'Alice' } });
fireEvent.click(screen.getByText('Soumettre'));
await waitFor(() => {
expect(mockAPI.submit).toHaveBeenCalledWith({ nom: 'Alice' });
});
});
Tests E2E
Tests d'interface utilisateur complets
javascript
// Avec Cypress
describe('Authentification', () => {
it('permet à l\'utilisateur de se connecter', () => {
cy.visit('/login');
cy.get('input[name=email]').type('[email protected]');
cy.get('input[name=password]').type('password123');
cy.get('button[type=submit]').click();
cy.url().should('include', '/dashboard');
});
});
État et gestion de données
State Management
Context API
Partage d'état global dans React
javascript
// Création du contexte
const ThemeContext = React.createContext('light');
// Provider
function App() {
const [theme, setTheme] = useState('light');
return (
<ThemeContext.Provider value={{ theme, setTheme }}>
<Main />
</ThemeContext.Provider>
);
}
// Utilisation
function Bouton() {
const { theme } = useContext(ThemeContext);
return <button className={theme}>Cliquez-moi</button>;
}
Redux
Gestion d'état prédictible
javascript
// Action
const INCREMENT = 'INCREMENT';
const incrementer = () => ({ type: INCREMENT });
// Reducer
function compteurReducer(state = 0, action) {
switch (action.type) {
case INCREMENT:
return state + 1;
default:
return state;
}
}
// Store
const store = Redux.createStore(compteurReducer);
store.subscribe(() => console.log(store.getState()));
store.dispatch(incrementer());
Débogage et Performance
Console API avancée
Méthodes avancées
Outils de débogage avancés
javascript
// Grouper les logs
console.group("Données utilisateur");
console.log("Nom:", utilisateur.nom);
console.log("Email:", utilisateur.email);
console.groupEnd();
// Tableau formaté
console.table([
{ nom: "Alice", age: 25 },
{ nom: "Bob", age: 30 }
]);
// Chronométrage
console.time("opération");
// opération longue...
console.timeEnd("opération");
// Comptage
function processItem(item) {
console.count("Items traités");
// traitement...
}
Performance
Performance API
Mesure précise des performances
javascript
performance.mark("debut-calcul");
// Code à mesurer
performance.mark("fin-calcul");
performance.measure("Durée calcul", "debut-calcul", "fin-calcul");
const mesures = performance.getEntriesByType("measure");
console.log(mesures[0].duration + " ms");
requestAnimationFrame
Animations fluides
javascript
function animer() {
// Mise à jour des éléments visibles
element.style.left = `${position++}px`;
// Planifie la prochaine mise à jour
if (position < 500) {
requestAnimationFrame(animer);
}
}
requestAnimationFrame(animer);
Tooling moderne
Build tools
Bundlers
Webpack, Rollup, Parcel, Vite
javascript
// webpack.config.js exemple simplifié
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
}
]
}
};
Package managers
npm, yarn, pnpm
bash
# npm
npm install react --save
npm run build
# yarn
yarn add react
yarn build
# pnpm (plus rapide et efficient en espace)
pnpm add react
pnpm build
ESLint et Prettier
Linting
Analyse statique du code
javascript
// .eslintrc.js
module.exports = {
extends: ['eslint:recommended', 'plugin:react/recommended'],
rules: {
'no-unused-vars': 'error',
'react/prop-types': 'warn'
}
};
Formatting
Formatage automatique du code
javascript
// .prettierrc
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5"
}
Frameworks et bibliothèques modernes
React
Hooks
Gestion d'état et cycle de vie dans les composants fonctionnels
javascript
function CompteurAvecEffets() {
const [compteur, setCompteur] = useState(0);
// Similaire à componentDidMount + componentDidUpdate
useEffect(() => {
document.title = `Vous avez cliqué ${compteur} fois`;
// Similaire à componentWillUnmount
return () => {
document.title = 'React App';
};
}, [compteur]); // Uniquement réexécuté si compteur change
return (
<div>
<p>Vous avez cliqué {compteur} fois</p>
<button onClick={() => setCompteur(compteur + 1)}>
Cliquez-moi
</button>
</div>
);
}
Custom Hooks
Extraction de logique réutilisable
javascript
function useLocalStorage(key, valeurInitiale) {
const [valeur, setValeur] = useState(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : valeurInitiale;
} catch (error) {
return valeurInitiale;
}
});
const setValue = value => {
try {
setValeur(value);
window.localStorage.setItem(key, JSON.stringify(value));
} catch (error) {
console.log(error);
}
};
return [valeur, setValue];
}
// Utilisation
function MonComposant() {
const [nom, setNom] = useLocalStorage('nom', '');
// ...
}
Vue.js
Composition API
Alternative à l'API Options
javascript
import { ref, computed, onMounted } from 'vue';
export default {
setup() {
const compteur = ref(0);
const double = computed(() => compteur.value * 2);
function incrementer() {
compteur.value++;
}
onMounted(() => {
console.log('Composant monté');
});
return {
compteur,
double,
incrementer
};
}
};
Angular
Decorators
Annotations pour définir les composants
typescript
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-salutation',
template: '<h1>Bonjour {{nom}}!</h1>'
})
export class SalutationComponent {
@Input() nom: string;
}
Tendances émergentes
WebAssembly (WASM)
Intégration avec JS
Exécution de code compilé dans le navigateur
javascript
// Chargement d'un module WebAssembly
WebAssembly.instantiateStreaming(fetch('module.wasm'))
.then(obj => {
// Appel d'une fonction exportée depuis WASM
const resultat = obj.instance.exports.calculer(10, 20);
console.log(resultat);
});
Web Components
Custom Elements
Composants réutilisables natifs
javascript
class MonComposant extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
:host { display: block; border: 1px solid black; }
</style>
<div>
<h2>Mon composant custom</h2>
<slot></slot>
</div>
`;
}
connectedCallback() {
console.log('Composant ajouté au DOM');
}
}
customElements.define('mon-composant', MonComposant);
CSS-in-JS
Styled Components
Styles encapsulés dans les composants
javascript
import styled from 'styled-components';
const Button = styled.button`
background: ${props => props.primary ? 'blue' : 'white'};
color: ${props => props.primary ? 'white' : 'blue'};
font-size: 1em;
padding: 0.25em 1em;
border: 2px solid blue;
border-radius: 3px;
`;
function App() {
return (
<div>
<Button>Normal</Button>
<Button primary>Primary</Button>
</div>
);
}
Sécurité en JavaScript
Attaques courantes
Cross-Site Scripting (XSS)
Injection de code malveillant
javascript
// Dangereux
element.innerHTML = userInput; // Potentiel XSS
// Sécurisé
element.textContent = userInput;
// ou
function escapeHTML(str) {
return str.replace(/[&<>"']/g, m => ({
'&': '&', '<': '<', '>': '>',
'"': '"', "'": '''
})[m]);
}
element.innerHTML = escapeHTML(userInput);
CSRF (Cross-Site Request Forgery)
Protection avec des tokens
javascript
// Ajout d'un token CSRF dans chaque requête
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
fetch('/api/action', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': csrfToken
},
body: JSON.stringify(data)
});
Validation des données
Schémas de validation
Vérification des données entrantes
javascript
// Avec une bibliothèque comme Joi ou Yup
const schema = Yup.object({
nom: Yup.string().required("Le nom est requis"),
email: Yup.string().email("Email invalide").required("L'email est requis"),
age: Yup.number().positive().integer().min(18).required()
});
try {
const donnees = await schema.validate(formData);
// Données valides
} catch (error) {
console.error("Erreur de validation:", error.message);
}
Architecture de code
Conception modulaire
Component-Based Architecture
Organisation par composants réutilisables
javascript
// Structure typique d'une application React
/src
/components
/Button
Button.js
Button.test.js
Button.css
/Card
Card.js
Card.test.js
Card.css
/pages
HomePage.js
ProfilePage.js
/services
api.js
auth.js
/utils
helpers.js
App.js
index.js
Feature-First Architecture
Organisation par fonctionnalités
javascript
/src
/features
/auth
/components
LoginForm.js
RegisterForm.js
/services
authService.js
authSlice.js
/products
/components
ProductList.js
ProductDetail.js
/services
productService.js
productSlice.js
/shared
/components
Button.js
Modal.js
/utils
helpers.js
App.js
index.js
Patrons architecturaux
Flux unidirectionnel
Flux de données à sens unique (React, Redux)
Action → Dispatcher → Store → View → Action → ...
MVC (Model-View-Controller)
Séparation des responsabilités
javascript
// Model: gestion des données
class UserModel {
constructor() {
this.users = [];
}
async fetchUsers() {
const response = await fetch('/api/users');
this.users = await response.json();
return this.users;
}
}
// View: affichage
class UserView {
render(users) {
const html = users.map(user => `<li>${user.name}</li>`).join('');
document.querySelector('.users-list').innerHTML = html;
}
}
// Controller: coordination
class UserController {
constructor(model, view) {
this.model = model;
this.view = view;
}
async init() {
const users = await this.model.fetchUsers();
this.view.render(users);
}
}
Accessibilité (a11y)
ARIA (Accessible Rich Internet Applications)
Attributs pour améliorer l'accessibilité
javascript
// Attributs ARIA
<button
aria-label="Fermer la boîte de dialogue"
aria-pressed="false"
onClick={fermerDialogue}
>
<span aria-hidden="true">×</span>
</button>
// Navigation au clavier
<div
role="tablist"
onKeyDown={handleKeyNavigation}
>
<button
role="tab"
tabIndex="0"
aria-selected="true"
>
Premier onglet
</button>
<button
role="tab"
tabIndex="-1"
aria-selected="false"
>
Second onglet
</button>
</div>
Focus management
Gestion du focus pour la navigation