Module 2 : JavaScript

Comprendre le fonctionnement de JS

Plongez au cœur du moteur JavaScript, comprenez la pile d'exécution, le tas mémoire et le cycle d'événements.

45 min
Version Audio
Débutant
🏗️

COMPRENDRE LE FONCTIONNEMENT DE JAVASCRIPT

Version Ultra-Détaillée

🏗️ 1. COMMENT LE NAVIGATEUR EXÉCUTE JAVASCRIPT

1.1 Le Processus Complet

┌─────────────────────────────────────────────────────────────────┐

│ PROCESSUS D'EXÉCUTION JS │

│ │

│ ┌─────────────┐ ┌─────────────┐ ┌───────────────────┐ │

│ │ TÉLÉCHARGEMENT │ → │ PARSING │ → │ COMPILATION JIT │ │

│ │ (HTML/CSS/JS) │ │ (AST) │ │ (Bytecode) │ │

│ └─────────────┘ └─────────────┘ └───────────────────┘ │

│ │

│ ┌─────────────────────────────────────────────────────────┐ │

│ │ EXÉCUTION │ │

│ │ ┌──────────────┐ ┌──────────────┐ │ │

│ │ │ CALL STACK │ │ HEAP MEMORY │ │ │

│ │ │ (Exécution) │ │ (Stockage) │ │ │

│ │ └──────────────┘ └──────────────┘ │ │

│ │ │ │

│ │ ┌──────────────────────────────────────────────────┐ │ │

│ │ │ EVENT LOOP │ │ │

│ │ │ Callback Queue → Call Stack (quand vide) │ │ │

│ │ └──────────────────────────────────────────────────┘ │ │

│ └─────────────────────────────────────────────────────────┘ │

│ │

│ ┌─────────────────────────────────────────────────────────┐ │

│ │ GARBAGE COLLECTOR │ │

│ │ (Nettoyage mémoire) │ │

│ └─────────────────────────────────────────────────────────┘ │

└─────────────────────────────────────────────────────────────────┘

ÉtapeDescriptionComposant
1. TéléchargementLe navigateur télécharge le fichier JSRéseau
2. ParsingAnalyse syntaxique du codeParser
3. ASTConversion en Arbre Syntaxique AbstraitParser
4. Compilation JITCompilation du bytecode ou code machineMoteur JS
5. ExécutionExécution du code sur la Call StackMoteur JS
6. Event LoopGestion des opérations asynchronesMoteur JS
7. GCNettoyage de la mémoireGarbage Collector

🔍 2. PARSING (ANALYSE SYNTAXIQUE)

2.1 Qu'est-ce que le Parsing ?

┌─────────────────────────────────────────────────────────────────┐

│ PROCESSUS DE PARSING │

│ │

│ ┌─────────────────────────────────────────────────────────┐ │

│ │ 1. SCANNEUR (Lexical Analysis) │ │

│ │ Code source → Tokens │ │

│ │ let x = 10; → [LET, IDENTIFIER, EQUALS, NUMBER, ;] │ │

│ └────────────────┬────────────────────────────────────────┘ │

│ ▼ │

│ ┌─────────────────────────────────────────────────────────┐ │

│ │ 2. PARSEUR (Syntactic Analysis) │ │

│ │ Tokens → AST (Abstract Syntax Tree) │ │

│ └────────────────┬────────────────────────────────────────┘ │

│ ▼ │

│ ┌─────────────────────────────────────────────────────────┐ │

│ │ 3. COMPILATION (Bytecode Generation) │ │

│ │ AST → Bytecode (pour l'interpréteur) │ │

│ └─────────────────────────────────────────────────────────┘ │

└─────────────────────────────────────────────────────────────────┘

Le Scanneur (Lexical Analysis)

JavaScript

// Code source

let

message = "Bonjour";

// Tokens générés

[

{ type: 'KEYWORD', value: 'let' },

{ type: 'IDENTIFIER', value: 'message' },

{ type: 'OPERATOR', value: '=' },

{ type: 'STRING', value: '"Bonjour"' },

{ type: 'PUNCTUATOR', value: ';' }

]

🗑️ 6. GARBAGE COLLECTOR (GC)

6.1 Qu'est-ce que le Garbage Collector ?

// Création d'objets

let

obj1 = { name: 'Alice' };

let

obj2 = { name: 'Bob' };

let

obj3 = { name: 'Charlie' };

// L'objet 'Alice' n'est plus référencé

obj1

= null;

// Le GC va supprimer { name: 'Alice' } de la mémoire

6.2 Le Cycle de Vie de la Mémoire

┌─────────────────────────────────────────────────────────────────┐

│ CYCLE DE VIE D'UN OBJET │

│ │

│ 1. ALLOCATION │

│ ┌─────────────────────────────────────────────────────────┐ │

│ │ let obj = { name: 'Jean' }; │ │

│ │ La mémoire est réservée pour l'objet │ │

│ └─────────────────────────────────────────────────────────┘ │

│ ▼ │

│ 2. UTILISATION │

│ ┌─────────────────────────────────────────────────────────┐ │

│ │ console.log(obj.name); │ │

│ │ L'objet est utilisé │ │

│ └─────────────────────────────────────────────────────────┘ │

│ ▼ │

│ 3. LIBÉRATION (GC) │

│ ┌─────────────────────────────────────────────────────────┐ │

│ │ obj = null; │ │

│ │ // Plus de références │ │

│ │ // GC libère la mémoire │ │

│ └─────────────────────────────────────────────────────────┘ │

└─────────────────────────────────────────────────────────────────┘

6.3 Les Algorithmes de GC

Mark-and-Sweep (Marquage puis Balayage)

Generational Garbage Collection

┌─────────────────────────────────────────────────────────────────┐

│ GÉNÉRATIONS DE V8 (Orinoco) │

│ │

│ ┌─────────────────────────────────────────────────────────┐ │

│ │ YOUNG GENERATION (Jeune) │ │

│ │ ┌─────────────┐ ┌─────────────┐ │ │

│ │ │ NEW SPACE │ → │ OLD SPACE │ Objets survécus │ │

│ │ │ (1-2 MB) │ │ (1-2 MB) │ → Promus en Old │ │

│ │ └─────────────┘ └─────────────┘ │ │

│ │ │ │

│ │ • GC fréquent (Minor GC) │ │

│ │ • Rapide (quelques ms) │ │

│ └─────────────────────────────────────────────────────────┘ │

│ ▼ │

│ ┌─────────────────────────────────────────────────────────┐ │

│ │ OLD GENERATION (Vieux) │ │

│ │ ┌─────────────────────────────────────────────────┐ │ │

│ │ │ OLD SPACE (100-500 MB) │ │ │

│ │ └─────────────────────────────────────────────────┘ │ │

│ │ │ │

│ │ • GC moins fréquent (Major GC) │ │

│ │ • Plus lent (plusieurs dizaines de ms) │ │

│ └─────────────────────────────────────────────────────────┘ │

│ │

│ ┌─────────────────────────────────────────────────────────┐ │

│ │ LARGE OBJECT SPACE │ │

│ │ Objets de plus de 1 MB (tableaux, buffers) │ │

│ └─────────────────────────────────────────────────────────┘ │

└─────────────────────────────────────────────────────────────────┘

🧵 7. SINGLE THREAD & EVENT LOOP

7.2 L'Event Loop

Le Cycle Complet

┌─────────────────────────────────────────────────────────────────┐

│ EVENT LOOP - CYCLE COMPLET │

│ │

│ ┌─────────────────────────────────────────────────────────┐ │

│ │ TIMERS │ │

│ │ Vérifie les setTimeout, setInterval │ │

│ │ Exécute les callbacks prêts │ │

│ └────────────────┬────────────────────────────────────────┘ │

│ ▼ │

│ ┌─────────────────────────────────────────────────────────┐ │

│ │ PENDING I/O │ │

│ │ Exécute les callbacks d'erreurs système │ │

│ └────────────────┬────────────────────────────────────────┘ │

│ ▼ │

│ ┌─────────────────────────────────────────────────────────┐ │

│ │ IDLE / PREPARE │ │

│ │ Usage interne (libuv) │ │

│ └────────────────┬────────────────────────────────────────┘ │

│ ▼ │

│ ┌─────────────────────────────────────────────────────────┐ │

│ │ POLL │ │

│ │ • Attend les nouveaux événements I/O │ │

│ │ • Exécute les callbacks I/O prêts │ │

│ │ • Peut bloquer (se mettre en pause) │ │

│ └────────────────┬────────────────────────────────────────┘ │

│ ▼ │

│ ┌─────────────────────────────────────────────────────────┐ │

│ │ CHECK │ │

│ │ Exécute les setImmediate │ │

│ └────────────────┬────────────────────────────────────────┘ │

│ ▼ │

│ ┌─────────────────────────────────────────────────────────┐ │

│ │ CLOSE CALLBACKS │ │

│ │ Fermeture des sockets, handles │ │

│ └─────────────────────────────────────────────────────────┘ │

│ │

│ 🔄 La boucle recommence ! │

└─────────────────────────────────────────────────────────────────┘

L'Event Loop en Détail

JavaScript

// Pseudo-code de l'Event Loop

while

(true) { // 1. Exécuter toutes les microtasks processMicrotasks(); // 2. Vérifier si la Call Stack est vide while (!callStack.isEmpty()) { callStack.executeNext(); } // 3. Prendre le prochain callback de la queue const callback = callbackQueue.dequeue(); if (callback) { callStack.push(callback); continue; } // 4. Si rien à faire, mettre en pause if (!hasTimers()) { waitForEvents(); } }

Exemple Concret

JavaScript

console.log('1. Début');

setTimeout

(() => { console.log('2. Timer (1000ms)'); }, 1000);

setTimeout

(() => { console.log('3. Timer (0ms)'); }, 0);

Promise.resolve() .then(() => console.log('4. Promise'));

console.log('5. Fin');

// Résultat :

// 1. Début

// 5. Fin

// 4. Promise

// 3. Timer (0ms)

// 2. Timer (1000ms)

7.3 La Call Stack

JavaScript

function

first() { console.log('first'); second(); }

function

second() { console.log('second'); third(); }

function

third() { console.log('third'); }

first();

// Call Stack :

// ═══════════════════════════════════════════════

// 1. [first()] ← Empilé

// 2. [first(), second()] ← Empilé

// 3. [first(), second(), third()] ← Empilé

// 4. [first(), second()] ← Dépilé

// 5. [first()] ← Dépilé

// 6. [] ← Vide

📊 RÉSUMÉ - PHASE 2.2

┌─────────────────────────────────────────────────────────────────┐

│ CYCLE DE VIE DU CODE JS │

│ │

│ Code Source │

│ ↓ │

│ Parsing (Scanning → Tokens) │

│ ↓ │

│ AST (Abstract Syntax Tree) │

│ ↓ │

│ Bytecode (Interprète comme Ignition) │

│ ↓ │

│ Exécution (Call Stack) │

│ ↓ │

│ Profilage (Fonctions "chaudes") │

│ ↓ │

│ JIT (Compilation → Code Machine) │

│ ↓ │

│ Exécution Optimisée │

│ ↓ │

│ Garbage Collector (Nettoyage mémoire) │

└─────────────────────────────────────────────────────────────────┘

ConceptDéfinitionRôle
ParsingAnalyse du code sourceTokens → AST
ASTArbre syntaxiqueReprésentation structurelle
BytecodeInstructions compactesExécution par l'interpréteur
JITCompilation Just-In-TimeOptimisation en code machine
GCGarbage CollectorLibération mémoire
Event LoopBoucle d'événementsGestion asynchrone
Call StackPile d'exécutionSuivi des appels
HeapTasse mémoireStockage des objets