Accueil

Traduction

Tutoriel sur Javascript

Recherche dans ce tuto

L'auteur : Patrick Darcheville

Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site

JavaScript : les boucles

Une boucle est un bloc d'instructions qui est exécuté N fois. Chaque passage dans la boucle est appelée une itération.

Ce bloc d'instructions est exécuté tant qu'une condition est vérifiée.

Incrémentation et décrémentation

Souvent la condition est basée sur une variable qui fait fonction de compteur ou de compte à rebours. C'est à dire que la variable doit être incrémentée (sa valeur augmente) OU être décrémentée (sa valeur diminue) à chaque itération.

Il y a trois façon d'écrire une instruction d'incrémentation.
Supposons que nous voulons incrémenter la variable vcompteur de 1.

La dernière solution est la plus utilisée.

Il y a aussi trois façons pour la décrémentation.
Supposons que nous voulons décrémenter la variable vrebours de 1.

La boucle while

Syntaxe

while (condition)
{
	instruction1 ; 	instruction2 ; ... 	instructionN; 
}

Fonctionnement

Le bloc d'instructions est exécuté tant que la condition retourne TRUE. Il y a sortie de la boucle dès que la condition retourne FALSE.
Le bloc d'instructions peut très bien ne jamais être exécuté ; il suffit que la condition retourne toujours FALSE !
Si la condition est toujours TRUE alors la boucle va se répéter à l'infini ... Ce qui est gênant.

Thème : contrôle de saisie d'un réel

Il s'agit de vérifier si on a bien saisi une donnée au format numérique.

Le script

let vnote; 
alert(typeof(vnote)); 
while (isNaN(vnote))
{ 
	vnote = prompt('tapez une note entière ou décimale') ;
}
alert('saisie correcte');; 

Je crée la variable vnote mais sans lui affecter de valeur. Donc elle est "undefined".
Donc la condition du while() retourne true.
Si j'avais affecté, par exemple, 0 à vnote le script n'aurait pas itéré.

Le rendu dans un nouvel onglet

Testez ce script !

La saisie d'un nombre réel est délicate pour un francophone. Il risque, par exemple, de saisir 10,5 et non pas 10.5 ce qui provoquera une erreur.
Donc tant que le contenu de la variable vnote n'est pas au format numérique (caractères : chiffres et un point) alors il faut recommencer la saisie.
Nous avons utilisé la fonction isNaN argumenté avec la variable vnote. isNaN est fonction JS qui est l'acronyme de "is Not a Numéric". Donc l'expression isNaN(vnote) retourne true si vnote contient "aaa" ou ou 10,5.

La boucle do ... while

Syntaxe

do 
{ 
	instruction1 ; instruction2; ....		; instructionN  ; 
}
while (condition) ; 

Il y a forcément au moins une itération puisque le test se fait en fin de boucle !

Le script

var vnote ; 
alert('attention le séparateur décimal est le point et non pas la virgule !') ; 
do  
	{ vnote = prompt('tapez une note entière ou décimale') ; 	}
while (isNaN(vnote)) ; 
alert('saisie correcte'); 

Le rendu dans un nouvel onglet

Testez ce script !

Ce programme fait exactement la même chose que le précédent : forcer l'utilisateur à répéter la saisie tant que le format n'est pas numérique. Mais la boucle do ... while est mieux adaptée puisqu'il y a forcément une itération

La boucle for historique

Je veux évoquer ici la boucle for(...; ... ; ...) qui exige trois instructions.
Il s'agit bien "d'instructions" (séparées par des ;) et non pas paramètres.

Syntaxe

for (initialisation ; condition ; incrémentation )
		{ instruction1 ; instruction2; ...}

Exemple : moyenne de trois notes

Le script correspondant

var note ; vsomme = 0 ; 
for(var vcompteur = 0; vcompteur < 3 ; vcompteur++)
{
	vnote= prompt('tapez une note entière ou décimale') ; 
	vsomme += parseFloat(vnote) ; 
	// nouveau cumul de points après conversion de la chaîne en réel
} // fin for 
var vmoyenne = vsomme / vcompteur ; 
alert('points : ' + vsomme); 
alert('moyenne : ' + vmoyenne) ; 

Toute saisie via la fonction prompt() est de type string (même s'il s'agit d'une suite de chiffres). Donc avant toute addition il faut convertir vnote en numérique avec la fonction parseFloat().
Je peux donc saisir un nombre décimal.

Le rendu dans un nouvel onglet

Testez ce script
Test 1 : saisissez les entiers 11 puis 12 et 13.
Test 2 : saisissez les entiers 11.5 puis 12.5 et 12.5
Test 3: saisissez les entiers 11,5 puis 11,5 et 11,5

Pour le dernier test le format de saisie n'est pas correct mais le script ne 'plante' pas ; ParseFloat() convertit la chaine à l'entier inférieur !

Moyenne de trois notes amélioré : version améliorée

Le script

Tant que la saisie n'est pas au format numérique (suite de chiffres et éventuellement un point) on reste dans la boucle do ... while().
L'utilisateur est informé d'une saisie correcte ou pas.

Le rendu

Testez la version améliorée

Les instructions BREAK et CONTINUE

Une boucle peut contenir les instructions break et continue.
Mais quel est l'intérêt d'utiliser ces instructions ?
En fait elles simplifient la programmation.
Je rappelle que JavaScript est sensible à la casse : il faut écrire ces deux instructions en minuscules dans les scripts.

Instruction BREAK dans une boucle

L'instruction break permet une sortie anticipée d'une boucle.
Cette instruction est toujours dans un test.

Thème : trois tentatives maximales pour saisie le mot de passe. Possibilité de sortir de la boucle dès la première saisie si cette dernière est correcte.

Le script correspondant

var valide = false; 
var vcompteur =0;
alert('pour la saisie du mot de passe vous avez droit à trois essais') ; 
while (vcompteur < 3)
{ 
	var vmot = prompt('saisir le mot de passe') ; 
	if(vmot=="sesame") {valide =true ; break;}
	vcompteur++;
}
if (valide) alert("vous êtes connecté!");
else alert("connexion impossible");

Une boucle est normalement exécutable 3 fois pour saisir le mot de passe.
Mais dès que le mot de passe saisi est valide ("sesame") valide passe à VRAI et sortie de la boucle (commande break).

Le rendu dans un autre onglet

Testez le script !

L'instruction break existe aussi dans la structure switch : permet de sortir test multiple après exécution d'un case.

Instruction CONTINUE dans une boucle

L'instruction continue dans une boucle permet l'arrêt de l'itération en cours et le passage à la suivante.
Comme break l'instruction continue est incluse dans un test.

Thème : un programme doit afficher les N premiers nombres pairs.
Donc si le reste de la division entière du nombre par 2 ne donne pas zéro il ne faut pas afficher ce nombre et passer à l'itération suivante.

Le script

var maxi =prompt("saisir un entier inférieur ou égal à 60"); 
maxi = parseInt(maxi); 	if (maxi >60) maxi =60; 
// la limite ne peut dépasser 60
for (var compteur = 1 ; compteur <= maxi; compteur++)
{	
	if(compteur%2 != 0) continue;
	document.write(compteur + " est un nombre pair ! 
"); }

Notez le test ; si le reste de la division entière est différent de zéro alors passage à l'itération suivante (instruction continue)
Notez que valeur initiale de compteur est 1 ; afin qu'on n'affiche pas que zéro est un nombre pair.

Le rendu dans un nouvel onglet

Testez ce code !

Une boucle infinie

Une boucle est dite infinie lorsque la condition de la boucle est toujours VRAI.

Ce qu'il ne faut pas faire

Le script :

let rebours =1000000 ; 
let i =1 ; 
while (i==1)
{
	rebours--; 
	document.write("
rebours : " + rebours); }

La boucle est vraiment sans fin puisqu'il n'y a pas de break dans le bloc d'instructions.
Heureusement les navigateurs ont intégré un sécurité ; si le script est trop long à s'exécuter, ils affichent un message proposant un "break manuel".

Un script correct avec deux boucles infinies

let cumul = 0;
for (; ;)
{
	cumul++; 
	document.write("
cumul : " + cumul); if (cumul > 49) break; } let rebours =50 ; let i =1 ; while (i==1) { rebours--; document.write("
rebours : " + rebours); if (rebours < 1) break; }

Préférez la deuxième solution !
Dans chaque boucle il faut bien sûr un instruction du genre if (condition) break pour quitter la boucle infinie.

Le rendu

Testez ce code !

les boucles for ... of et for ... in

La boucle for ... of

Ce type récent de boucle permet de parcourir un objet de type Array (tableau indicé) très simplement.
En effet le programmeur n'a pas besoin de gérer l'indice de l'élément ; la boucle for ... of ... s'en charge !

Exemple : le rendu

Ci-dessous un document HTML dans un Iframe :

Cliquez sur le bouton de commmande !
Des infos sur chaque image du document s'affichent.

Le code de ce document

Ce document comprend cinq images.
Chaque image a trois attributs : src, id, alt

Notez la technique pour produire le contenu du DIV identifié "message" : à chaque itération un paragraphe est ajouté à ce conteneur.
Notez aussi la notation 'template strings' dans la dernière instruction.

La variable images produite par la méthode document.querySelectorAll('img') est un 'array'.
Ce tableau référence toutes les images du document HTML.
Remarque : Les 'arrays' sont évoqués dans le chapitre 6
La boucle for ... of ... affiche pour chaque image la valeur de sa source, de son ID et de sa légende.

La boucle for ... in

Ne confondez for(... in...) et for(... of...) !

La boucle for...of ... est utilisée pour itérer sur les valeurs des objets itérables tels que les 'arrays' (tableaux indicés), les chaînes de caractères, les 'Sets' (ensembles), les 'Maps' (tableaux associatifs).

La boucle for...in est utilisée pour itérer sur les clés.

Exemple d'utilisation de for ... in ...

Le rendu

Le script affiche les différentes clés de l'objet.
J'aurais pu utiliser la méthode forEach() pour afficher les clés de l'objet. Voir ci-dessous !

La méthode forEach()

Cette méthode forEach() peut s'appliquer à différentes structures de données : arrays, maps, sets et même à des objets (à condition de le convertir au préalable).
Cette méthode est très souple ; on peut afficher uniquement les valeurs, OU uniquement les clés OU les clés:valeurs.
Remarque : Les 'tableaux' map & set sont évoqués dans le chapitre 6

Le script de l'exemple

La méthode Object.entries() permet de convertir un objet en un tableau de paires clé-valeur, facilitant entre autres le parcours de l'objet.

Notez la notation 'template strings' pour la dernière instruction.

Le rendu dans un nouvel onglet

Cliquez ici !

Attention : affichage dans la console !