MINISTERE DE L’ECONOMIE NUMERIQUE REPUBLIQUE GABONAISE
Union – Travail – Justice
FILIERE : GENIE INFORMATIQUE
THEME : JAVASCRIPT AVANC É
Membres du groupe : Sous la direction de :
• Mr BONGO MBONGO
• ANDEME MBO Lidvige Johane
ESSINGONE Ghandy Steeve
• HOMDOUM Janvier Boreil
• MAMBA NZAHOU Jasmine Esmeralda
• BOUSSENGUI MBOUALA Jacques Danis
• NGUIZI HANDJA NTCHOUAN Emmanuellie Lisy
• MOUBOUENGHOU MOUKAGNI Merveilles
Verônne
• MINKO Antoine Kelly
• BIGNOUMBA DIVASSA Layka Bernadette
Promotion 2024-2025
SOMMAIRE
INTRODUCTION ........................................................................................................................ 1
PREMIÈRE PARTIE : LES FONDEMENTS DE LA PROGRAMMATION JAVASCRIPT
AVANCÉE ................................................................................................................................ 2
CHAPITRE I : LES FONCTIONS AVANCÉES .................................................................. 3
Section 1 : Les closures et leur utilisation ...................................................................... 3
Section 2 : Les fonctions de rappel (callbacks) .............................................................. 3
Section 3 : Les fonctions récursives ................................................................................ 4
CHAPITRE II : LA PROGRAMMATION ASYNCHRONE ............................................... 6
Section 1 : Introduction à l'asynchrone : setTimeout et setInterval ............................ 6
Section 2 : Les promesses (Promise) : création et chaînage (then, catch, finally) ...... 7
Section 3 : Async/Await : syntaxe et utilisation ........................................................... 10
DEUXIÈME PARTIE : GESTION DES ERREURS ET MANIPULATION AVANCÉE DES
OBJETS ................................................................................................................................... 12
CHAPITRE I : LA GESTION DES ERREURS EN JAVASCRIPT .................................. 13
Section 1 : Les blocs try...catch ..................................................................................... 13
Section 2 : Gestion des erreurs dans les promesses et async/await ............................ 13
CHAPITRE II : MANIPULATION AVANCÉE DES OBJETS ......................................... 15
Section 1 : Prototypes et héritage en JavaScript ......................................................... 15
Section 2 : Méthodes statiques et méthodes d'instance ............................................... 15
Section 3 : Object.create, Object.assign, Object.defineProperty ............................... 15
CONCLUSION ....................................................................................................................... 17
BIBIOGRAPHIE ..................................................................................................................... 18
INTRODUCTION
JavaScript s’est imposé comme un langage incontournable du développement web, offrant aux
développeurs une grande souplesse pour créer des interfaces riches, dynamiques et interactives.
Au-delà de ses bases syntaxiques, JavaScript propose un ensemble de fonctionnalités avancées
qui permettent d’écrire du code plus expressif, modulaire et robuste. Ces concepts avancés
deviennent essentiels dans un environnement où les applications web se complexifient et où les
exigences de performance, d’ergonomie et de fiabilité sont croissantes.
Dans quelle mesure la maîtrise des concepts avancés de JavaScript — tels que les fonctions de
haut niveau, la programmation asynchrone, la gestion des erreurs et la manipulation des objets
— contribue-t-elle à améliorer la qualité, la lisibilité et l’efficacité du code dans des projets web
modernes ?
Pour répondre à cette problématique, ce rapport est organisé en deux grandes parties, chacune
abordant des aspects clés de la programmation avancée en JavaScript :
La première partie est consacrée aux fondements de la programmation JavaScript avancée.
Le chapitre I explore en profondeur les fonctions avancées, incluant les closures, les fonctions
de rappel (callbacks), ainsi que les fonctions récursives, qui sont essentielles pour la création de
structures logiques performantes.
Le chapitre II s'intéresse à la programmation asynchrone, en présentant des outils
fondamentaux comme setTimeout et setInterval, puis en détaillant l’usage des promesses
(Promise) et la syntaxe moderne async/await.
La deuxième partie se concentre sur la gestion des erreurs et la manipulation avancée des
objets, deux piliers indispensables à la robustesse et à la maintenabilité du code.
Le chapitre I traite de la gestion des erreurs, en montrant comment utiliser les blocs try...catch
et gérer efficacement les erreurs dans les contextes asynchrones.
Le chapitre II aborde la manipulation avancée des objets, en s'appuyant sur des notions telles
que les prototypes, les méthodes statiques et d’instance, ainsi que les outils fournis par l’API
Object (Object.create, Object.assign, Object.defineProperty)..
1
PREMIÈRE PARTIE : LES FONDEMENTS DE LA
PROGRAMMATION JAVASCRIPT AVANCÉE
2
CHAPITRE I : LES FONCTIONS AVANCÉES
Section 1 : Les closures et leur utilisation
Les closures (ou fermetures) constituent un concept fondamental en JavaScript qui permet de
créer des environnements lexicaux préservés. Selon Mozilla Developer Network :
« Une fermeture est la paire formée d'une fonction et des références à son état environnant
(l'environnement lexical) » [1]
Les closures permettent aux fonctions de conserver l'accès aux variables définies dans leur
portée externe, même après que cette portée a terminé son exécution. Cette caractéristique est
particulièrement utile pour l'encapsulation de données et la création de fonctions de fabrique.
Les closures sont largement utilisées dans le développement JavaScript moderne pour :
• Créer des variables privées
• Implémenter des modules
• Développer des fonctions de rappel avec état
• Mémoriser des résultats (memoization)
L'exemple suivant illustre qu’en JavaScript, une fermeture est créée chaque fois qu'une fonction est
créée :
function init() {
var nom = "Mozilla"; // nom est une variable locale de init
function afficheNom() {
// afficheNom est une fonction interne de init
console.log(nom); // ici nom est une variable libre (définie dans
la fonction parente)
}
afficheNom();
}
init()
Exemple 1 : Exemples de closures
3
Section 2 : Les fonctions de rappel (callbacks)
Les callbacks constituent un modèle fondamental pour la gestion des opérations asynchrones en
JavaScript. Comme l'explique la documentation de Mozilla Developer Network :
« Une fonction de rappel (aussi appelée callback en anglais) est une fonction passée dans une
autre fonction en tant qu'argument, qui est ensuite invoquée à l'intérieur de la fonction externe
pour accomplir une sorte de routine ou d'action. » [2]
L'exemple suivant illustre un callback synchrone simple :
function salutation(name) {
alert("Bonjour " + name);
}
function processUserInput(callback) {
var name = prompt("Entrez votre nom.");
callback(name);
}
processUserInput(salutation);
Exemple 2 : une fonction de rappel (callback)
Il est important de noter que les callbacks peuvent être synchrones (exécutés immédiatement)
ou asynchrones (exécutés ultérieurement). Les callbacks asynchrones sont particulièrement
utiles pour gérer des opérations comme les requêtes réseau, les minuteries, ou les événements
utilisateur.
Section 3 : Les fonctions récursives
La récursion est une technique puissante qui permet à une fonction de s'appeler elle-même pour
résoudre des problèmes complexes. Haverbeke explique ce concept ainsi :
« Il est tout à fait acceptable qu'une fonction s'appelle elle-même, tant que cela ne se produit pas
si souvent que cela provoque un débordement de pile (stack overflow). Une fonction qui
s'appelle elle-même est appelée fonction récursive. La récursion permet d'écrire certaines
fonctions dans un style différent. » [3] , traduction libre.
4
Un exemple classique de fonction récursive est le calcul d'une puissance, comme illustré par
Haverbeke :
function power(base, exponent) {
if (exponent === 0) {
return 1;
} else if (exponent < 0) {
return 1 / power(base, -exponent); // Modification pour
gérer les exposants négatifs
} else {
return base * power(base, exponent - 1);
}
}
Exemple 3 : Une fonction récursive
Cette fonction calcule la puissance en s'appelant elle-même avec un exposant décrémenté
jusqu'à atteindre le cas de base (exposant = 0). Cependant, il convient de noter que les
implémentations récursives peuvent être moins performantes que leurs équivalents itératifs :
« dans les implémentations JavaScript classiques, elle est environ trois fois plus lente que la
version avec une boucle. Parcourir une boucle simple coûte généralement moins cher que
d'appeler une fonction plusieurs fois. »
5
CHAPITRE II : LA PROGRAMMATION ASYNCHRONE
Section 1 : Introduction à l'asynchrone : setTimeout et setInterval
Le modèle d'exécution asynchrone est au cœur de JavaScript, permettant d'exécuter des
opérations sans bloquer le thread principal. Les fonctions setTimeout et setInterval constituent
la base de la programmation asynchrone en JavaScript. Comme l'explique Flanagan :
« Minuteries (Timers). setTimeout() et setInterval() permettent d'enregistrer une fonction à
invoquer une fois ou de manière répétée après un délai spécifié. Ces fonctions globales sont
essentielles en JavaScript côté client et sont donc définies comme des méthodes de l'objet
Window. Cependant, ce sont des fonctions à usage général et n'ont pas de lien direct avec la
fenêtre. La méthode setTimeout() de l'objet Window programme une fonction à exécuter après
un nombre spécifié de millisecondes. Elle renvoie un identifiant qu'on peut utiliser avec
clearTimeout() pour annuler l'exécution de la fonction programmée. setInterval() fonctionne
comme setTimeout(), mais la fonction spécifiée est invoquée de manière répétée à des
intervalles fixes (en millisecondes) :
setInterval(updateClock, 60000); // Appelle updateClock() toutes les 60
secondes
Comme setTimeout(), setInterval() renvoie une valeur utilisable avec clearInterval() pour
annuler les invocations futures. Il est possible de passer une chaîne de caractères comme
premier argument à setTimeout() et setInterval(). Cette chaîne sera évaluée (comme avec
eval()). HTML5 (et tous les navigateurs sauf IE) autorise des arguments supplémentaires après
les deux premiers, qui seront passés à la fonction invoquée. Pour une compatibilité avec IE,
évitez cette fonctionnalité. » [4], traduction libre.
Voici un exemple d'une fonction utilitaire avancée utilisant setTimeout et setInterval pour
programmer des exécutions futures :
/**
* Programme une ou plusieurs invocations de f() dans le futur.
* Attend 'start' millisecondes, puis appelle f() toutes les 'interval'
millisecondes,
* et s'arrête après 'end' millisecondes au total.
* Si 'interval' est omis, f() n'est invoquée qu'une fois après 'start' ms.
* Si seul 'f' est spécifié, 'start' est considéré comme 0.
* Note : l'appel à invoke() est non bloquant.
6
*/
function invoke(f, start, interval, end) {
if (!start) start = 0; // Par défaut : 0 ms
if (arguments.length <= 2) // Cas d'une seule invocation
setTimeout(f, start); // Invocation unique après 'start' ms
else { // Cas d'invocations multiples
setTimeout(repeat, start); // Répétitions commencent après 'start'
ms
}
function repeat() {
var h = setInterval(f, interval); // Invoque f() toutes les
'interval' ms
if (end) // Arrête après 'end' ms si 'end' est défini
setTimeout(function() { clearInterval(h); }, end);
}
}
processUserInput(salutation);
Exemple 4 : La Fonction invoke
Cette fonction illustre la puissance des timers en JavaScript pour créer des schémas d'exécution
complexes.
Section 2 : Les promesses (Promise) : création et chaînage (then, catch, finally)
Les Promises représentent une évolution significative par rapport aux callbacks pour gérer les
opérations asynchrones. Selon Marcel Souza dans son cours "MAÎTRISER JAVASCRIPT" :
« Les promesses sont une fonctionnalité JavaScript qui nous permet de gérer les opérations
asynchrones de manière plus élégante et ordonnée. Avec Promises, nous pouvons éviter ce que
l'on appelle 'l'enfer des rappels', un scénario courant lorsqu'il s'agit de plusieurs requêtes
asynchrones enchaînées. Au lieu de cela, nous pouvons enchaîner les opérations asynchrones de
manière linéaire et plus lisible. » [5]
Une Promise représente une valeur potentiellement disponible dans le futur et peut se trouver
dans l'un des trois états suivants :
• En attente : l'opération asynchrone n'est pas encore terminée
• Réalisé : l'opération asynchrone s'est terminée avec succès
• Rejeté : l'opération asynchrone a échoué
7
La création d'une Promise se fait à l'aide du constructeur Promise qui prend une fonction avec
deux paramètres : résoudre et rejeter :
function maPromesse() {
return new Promise(function(résoudre, rejeter) {
// Simule une opération asynchrone qui sera résolue après 2
secondes
setTimeout(function() {
résoudre('Opération terminée avec succès !');
}, 2000);
});
}
Exemple 5 : La Fonction maPromesse
L'enchaînement des opérations est réalisé via la méthode then() qui permet d'effectuer des
actions lorsque la promesse est résolue :
maPromesse()
.then(function(résultat) {
console.log(résultat); // 'Opération terminée avec succès !'
})
Exemple 6 : la méthode then()
La gestion des erreurs se fait à l'aide de la méthode catch() qui intercepte les rejets de promesses
:
function maPromesseAvecErreur() {
return new Promise(function(résoudre, rejeter) {
// Simule une opération asynchrone qui sera rejetée au bout de 2
secondes
setTimeout(function() {
rejeter('Erreur d\'opération !');
}, 2000);
});
}
maPromesseAvecErreur()
.then(function(résultat) {
console.log(résultat);
})
.catch(function(erreur) {
console.log(erreur); // 'Erreur d'opération !'
8
});
Exemple 7 : La méthode catch
9
Section 3 : Async/Await : syntaxe et utilisation
Async/Await constitue la syntaxe la plus récente pour gérer l'asynchronicité en JavaScript,
permettant d'écrire du code asynchrone qui ressemble à du code synchrone. Selon l'ouvrage
« Mastering Asynchronous JavaScript » :
« L'introduction d'async/await représente un changement de paradigme qui redéfinit la
programmation asynchrone en permettant aux développeurs d'écrire du code ressemblant à une
exécution synchrone sans bloquer les threads. Sous le capot, le mécanisme async/await est un
sucre syntaxique au-dessus des promesses, abstraisant efficacement les complexités de
l'enchaînement des promesses et de la gestion des erreurs. » [6], traduction libre.
Le mot-clé async déclaré sur une fonction garantit que cette fonction retourne toujours une
promesse, tandis que await suspend temporairement l'exécution de la fonction jusqu'à ce que la
promesse attendue soit résolue ou rejetée. Cette approche améliore considérablement la lisibilité
du code asynchrone.
Comparons l'implémentation basée sur les promesses avec l'approche async/await :
Avec Promises :
// Supposons que fetchData est une fonction asynchrone qui récupère des
données depuis une API
fetchData(url)
.then(response => processResponse(response))
.then(processedData => saveData(processedData))
.catch(error => console.error("Error occurred:", error));
Exemple 8 : promesses avec fetchData
Avec Async/Await :
async function handleData(url) {
try {
const response = await fetchData(url);
const processedData = await processResponse(response);
await saveData(processedData);
} catch (error) {
console.error("Error occurred:", error);
}
10
}
Exemple 9 : La syntaxe async/await
Cette nouvelle syntaxe améliore principalement la lisibilité et la gestion du code: « Les moteurs
JavaScript ont été affinés pour mieux optimiser le code asynchrone en analysant les points de
suspension créés par await. Cela permet une planification améliorée et une réduction de la
surcharge par rapport aux chaînes de promesses profondément imbriquées. » [6], traduction
libre.
11
DEUXIÈME PARTIE : GESTION DES ERREURS ET MANIPULATION
AVANCÉE DES OBJETS
12
CHAPITRE I : LA GESTION DES ERREURS EN JAVASCRIPT
Section 1 : Les blocs try...catch
La gestion des erreurs est essentielle pour créer des applications JavaScript robustes.
L'instruction try...catch fournit un mécanisme pour capturer et gérer les exceptions. Selon la
documentation MDN :
« L'instruction try...catch regroupe des instructions à exécuter et définit une réponse si l'une de
ces instructions provoque une exception. » [7]
Voici un exemple simple d'utilisation de try...catch :
try {
nonExistentFunction();
} catch (error) {
console.error(error);
// Expected output: ReferenceError: nonExistentFunction is not defined
// (Note: the exact output may be browser-dependent)
}
Exemple 10 : Utilisation de try...catch
Cette structure permet de capturer les erreurs qui pourraient survenir pendant l'exécution et de
définir un comportement alternatif plutôt que de laisser l'application échouer.
Section 2 : Gestion des erreurs dans les promesses et async/await
La gestion des erreurs évolue avec les différents modèles de programmation asynchrone. Clark
[8] présente une analyse comparative de la gestion des erreurs dans les trois principaux modèles
asynchrones :
• Pour les callbacks, la gestion d'erreurs est « décentralisée, manuelle »
• Pour les Promises, elle devient « centralisée via catch() »
• Pour Async/Await, elle est « simplifiée via try/catch »
Pour les Promises, Clark indique qu'elles offrent une « gestion d'erreurs centralisée » [8],
permettant de capturer les erreurs à un seul endroit grâce à la méthode .catch().
13
Pour async/await, l'auteur note une approche « simplifiée via try/catch » [8], permettant
d'utiliser la syntaxe familière des blocs try/catch synchrones pour gérer les erreurs dans un code
asynchrone, rendant le code « plus facile à lire et à maintenir » [8], traduction libre.
Cette approche est illustrée dans l'exemple suivant tiré de « Mastering Asynchronous
JavaScript » :
async function handleData(url) {
try {
const response = await fetchData(url);
const processedData = await processResponse(response);
await saveData(processedData);
} catch (error) {
console.error("Error occurred:", error);
}
}
Exemple 11 : Le bloc try/catch
Dans cet exemple, un seul bloc try/catch est capable de gérer les erreurs potentielles de toutes
les opérations asynchrones à l'intérieur de la fonction, ce qui est beaucoup plus intuitif que le
chaînage de .catch() dans les promesses.
14
CHAPITRE II : MANIPULATION AVANCÉE DES OBJETS
Section 1 : Prototypes et héritage en JavaScript
Le système de prototypes est au cœur du modèle d'héritage en JavaScript. Selon Marcel Souza,
dans « COURS COMPLET MAÎTRISER JAVASCRIPT » :
« Le prototype est un mécanisme fondamental en JavaScript qui permet l'héritage et le partage
de propriétés entre objets. Chaque objet en JavaScript possède une propriété interne appelée
[[Prototype]] qui pointe vers un autre objet duquel il hérite des propriétés et des méthodes. » [9]
Le système de prototype de JavaScript diffère des systèmes de classes traditionnels des
langages comme Java ou C++. Dans JavaScript, l'héritage se fait via une chaîne de prototypes,
où chaque objet peut hériter des propriétés et méthodes de son prototype.
Section 2 : Méthodes statiques et méthodes d'instance
Les méthodes statiques et d'instance représentent deux approches différentes pour définir des
comportements sur les objets en JavaScript.
Les méthodes d'instance sont définies sur le prototype d'une classe et sont accessibles via les
instances de cette classe. Elles peuvent accéder et manipuler les propriétés spécifiques à
l'instance via le mot-clé this.
Les méthodes statiques, en revanche, sont définies directement sur la classe elle-même, et non
sur son prototype. Elles ne sont pas accessibles aux instances et ne peuvent pas accéder aux
propriétés spécifiques à l'instance. Elles sont généralement utilisées pour des utilitaires liés à la
classe mais qui n'opèrent pas sur les données d'instance.
Section 3 : Object.create, Object.assign, Object.defineProperty
JavaScript offre plusieurs méthodes natives pour créer et manipuler des objets de manière
avancée :
• Object.create(proto, [propertiesObject]) : Crée un nouvel objet avec l'objet prototype spécifié
et les propriétés optionnelles.
• Object.assign(target, ...sources) : Copie les valeurs de toutes les propriétés énumérables
propres d'un ou plusieurs objets sources vers un objet cible. Il renvoie l'objet cible
modifié.
15
• Object.defineProperty(obj, prop, descriptor) : Définit une nouvelle propriété directement sur un
objet, ou modifie une propriété existante, et renvoie l'objet. Cette méthode permet un
contrôle précis sur le comportement des propriétés (writable, enumerable, configurable).
Ces méthodes sont essentielles pour la manipulation avancée des objets et la mise en œuvre de
modèles de conception complexes en JavaScript.
16
CONCLUSION
JavaScript offre un riche ensemble de fonctionnalités avancées qui permettent aux développeurs
de créer des applications complexes et robustes. Des closures aux promesses, en passant par les
prototypes et la gestion des erreurs, ces concepts constituent les fondements de la
programmation JavaScript moderne.
L'évolution des modèles de programmation asynchrone illustre particulièrement bien la
maturation de JavaScript en tant que langage. Des callbacks aux promesses, puis à la syntaxe
async/await, chaque étape a offert des abstractions plus puissantes et intuitives, permettant
d'écrire du code plus lisible et maintenable.
La maîtrise de ces concepts avancés est essentielle pour tout développeur souhaitant exploiter
pleinement la puissance de JavaScript. Elle permet non seulement d'écrire du code plus propre
et plus efficace, mais aussi de tirer parti des optimisations internes des moteurs JavaScript
modernes, qui sont particulièrement performants avec les patterns asynchrones actuels.
En conclusion, la compréhension approfondie des fonctions avancées, de la programmation
asynchrone, de la gestion des erreurs et de la manipulation avancée des objets constitue un socle
solide pour tout développeur JavaScript souhaitant créer des applications web performantes et
résilientes.
17
BIBLIOGRAPHIE
[1] Mozilla Developer Network, "Closures," MDN Web Docs, [En ligne]. Disponible :
https://developer.mozilla.org/fr/docs/Web/JavaScript/Closures . [Consulté le 19 avril 2025]
[2] Mozilla Developer Network, "Closures," MDN Web Docs, [En ligne]. Disponible :
https://developer.mozilla.org/fr/docs/Glossary/Callback_function . [Consulté le 19 avril 2025]
[3] M. Haverbeke, Eloquent JavaScript: A Modern Introduction to Programming, 3rd ed. San
Francisco, CA, USA: No Starch Press, 2018, p. 50.
[3] Mozilla Developer Network, "Callback function," MDN Web Docs, [En ligne]. Disponible :
https://developer.mozilla.org/fr/docs/Glossary/Callback_function . [Consulté le 19 avril 2025]
[4] D. Flanagan, JavaScript: The Definitive Guide. United Kingdom: O'Reilly Media, 2011, pp.
341-342.
[5] Marcel Souza, Maîtriser Javascript : Du Front-End Au Back-End. (n.d.). (n.p.): Gavea Lab
p. 34.
[6] Mastering Asynchronous JavaScript: Unlock the Secrets of Expert-Level Skills. Walzone
Press, 2025.
[7] Mozilla Developer Network, "try...catch," MDN Web Docs, [En ligne]. Disponible :
https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Statements/try...catch .
[Consulté le 19 avril 2025]
[8] W. E. Clark, JavaScript Functional Programming Made Simple: A Practical Guide with
Examples. Walzone Press, p. 47.
[9] M. Souza, COURS COMPLET MAÎTRISER JAVASCRIPT. Gavea, pp. 103-105.
18