Les programmeurs sont réputés pour être des gens fainéants, ce qui n'est pas totalement faux puisque le but de la programmation est de faire exécuter des choses à un ordinateur, pour ne pas les faire nous-mêmes. Ce chapitre va mettre en lumière ce comportement intéressant : nous allons en effet voir comment répéter des actions, pour ne pas écrire plusieurs fois les mêmes instructions. Mais avant ça, nous allons aborder le sujet de l'incrémentation.
Considérons le calcul suivant :
var number = 0;
number = number + 1;
La
variablenumber
contient donc la valeur 1. Seulement l'instruction pour
ajouter 1 est assez lourde à écrire et souvenez-vous, nous sommes des fainéants. Le JavaScript, comme d'autres
langages de programmation, permet ce que l'on appelle l'incrémentation, ainsi que son contraire, la
décrémentation.
L'incrémentation permet d'ajouter une unité à un nombre au moyen d'une syntaxe courte. À l'inverse, la décrémentation permet de soustraire une unité.
var number = 0;
number++;
alert(number); // Affiche : « 1 »
number--;
alert(number); // Affiche : « 0 »
Il s'agit donc d'une méthode assez rapide pour ajouter ou soustraire une unité à une variable (on dit incrémenter et décrémenter), et cela nous sera particulièrement utile tout au long de ce chapitre.
Il existe deux manières d'utiliser l'incrémentation en fonction de la position de l'opérateur ++ (ou --). On a vu qu'il pouvait se placer après la variable, mais il peut aussi se placer avant. Petit exemple :
var number_1 = 0;
var number_2 = 0;
number_1++;
++number_2;
alert(number_1); // Affiche : « 1 »
alert(number_2); // Affiche : « 1 »
number_1
etnumber_2
ont
tous deux été incrémentés. Quelle est donc la différence entre les deux procédés ?
La différence réside en fait dans la priorité de l'opération, et ça a
de l'importance si vous voulez récupérer le résultat de l'incrémentation. Dans l'exemple
suivant,++number
retourne la valeur
denumber
incrémentée, c'est-à-dire 1.
var number = 0;
var output = ++number;
alert(number); // Affiche : « 1 »
alert(output); // Affiche : « 1 »
Maintenant, si on place l'opérateur
après la variable à incrémenter, l'opération retourne la valeur
denumber
avant qu'elle ne soit incrémentée :
var number = 0;
var output = number++;
alert(number); // Affiche : « 1 »
alert(output); // Affiche : « 0 »
Ici donc,
l'opérationnumber++
a retourné la valeur
denumber
non incrémentée.
Une boucle est une structure analogue aux structures conditionnelles vues dans le chapitre précédent sauf qu'ici il s'agit de répéter une série d'instructions. La répétition se fait jusqu'à ce qu'on dise à la boucle de s'arrêter. À chaque fois que la boucle se répète on parle d'itération (qui est en fait un synonyme de répétition).
Pour faire fonctionner une boucle, il est nécessaire de
définir une condition. Tant que celle-ci est vraie (true
), la boucle
se répète. Dès que la condition est fausse (false
), la boucle
s'arrête.
Voici un exemple de la syntaxe d'une
bouclewhile
:
while (condition) {
instruction_1;
instruction_2;
instruction_3;
}
La bouclewhile
se
répète tant que la condition est validée. Cela veut donc dire qu'il faut s'arranger, à un moment, pour que la
condition ne soit plus vraie, sinon la boucle se répéterait à l'infini, ce qui serait fâcheux.
En guise d'exemple, on va incrémenter un nombre, qui vaut 1, jusqu'à ce qu'il vaille 10 :
var number = 1;
while (number < 10) {
number++;
}
alert(number); // Affiche : « 10 »
Au
départ,number
vaut 1. Arrive ensuite la boucle qui va demander
sinumber
est strictement plus petit que 10. Comme c'est vrai, la
boucle est exécutée, etnumber
est incrémenté. À chaque fois que les
instructions présentes dans la boucle sont exécutées, la condition de la boucle est réévaluée pour savoir s'il faut
réexécuter la boucle ou non. Dans cet exemple, la boucle se répète jusqu'à ce
quenumber
soit égal à 10. Sinumber
vaut
10, la conditionnumber < 10
est fausse, et la boucle s'arrête.
Quand la boucle s'arrête, les instructions qui suivent la boucle (la
fonctionalert()
dans notre exemple) sont exécutées normalement.
Imaginons un petit script qui va demander à l'internaute son prénom,
ainsi que les prénoms de ses frères et sœurs. Ce n'est pas compliqué à faire direz-vous, puisqu'il s'agit d'afficher
une boîte de dialogue à l'aide deprompt()
pour chaque prénom.
Seulement, comment savoir à l'avance le nombre de frères et sœurs ?
Nous allons utiliser une
bouclewhile
, qui va demander, à chaque passage dans la boucle, un
prénom supplémentaire. La boucle ne s'arrêtera que lorsque l'utilisateur choisira de ne plus entrer de prénom.
var nicks = '',
nick,
proceed = true;
while (proceed) {
nick = prompt('Entrez un prénom :');
if (nick) {
nicks += nick + ' '; // Ajoute le nouveau prénom ainsi qu'une espace juste après
} else {
proceed = false; // Aucun prénom n'a été entré, donc on fait en sorte d'invalider la condition
}
}
alert(nicks); // Affiche les prénoms à la suite
La
variableproceed
est ce qu'on appelle une variable
témoin, ou bien une variable de boucle. C'est une variable qui n'intervient pas
directement dans les instructions de la boucle mais qui sert juste pour tester la condition. Nous avons choisi de la
nommerproceed
, qui veut dire « poursuivre » en anglais.
À chaque passage dans la boucle, un prénom est demandé et sauvé
temporairement dans la variablenick
. On effectue alors un test
surnick
pour savoir si elle contient quelque chose, et dans ce cas, on
ajoute le prénom à la variablenicks
. Remarquez que nous ajoutons
aussi un espace, pour séparer les prénoms. Si par contrenick
contient
la valeurnull
— ce qui veut dire que l'utilisateur n'a pas entré de
prénom ou a cliqué surAnnuler
— on change la valeur
deproceed
enfalse
, ce
qui invalidera la condition, et cela empêchera la boucle de refaire une itération.
break
Dans l'exemple des prénoms, nous utilisons une variable de boucle
pour pouvoir arrêter la boucle. Cependant, il existe un mot-clé pour arrêter la boucle d'un seul coup. Ce mot-clé
estbreak
, et il s'utilise exactement comme dans la structure
conditionnelleswitch
, vue au chapitre précédent. Si l'on reprend
l'exemple, voici ce que ça donne avec unbreak
:
var nicks = '',
nick;
while (true) {
nick = prompt('Entrez un prénom :');
if (nick) {
nicks += nick + ' '; // Ajoute le nouveau prénom ainsi qu'une espace juste après
} else {
break; // On quitte la boucle
}
}
alert(nicks); // Affiche les prénoms à la suite
continue
Cette instruction est plus rare, car les opportunités de l'utiliser
ne sont pas toujours fréquentes.continue
, un peu
commebreak
, permet de mettre fin à une itération, mais attention,
elle ne provoque pas la fin de la boucle : l'itération en cours est stoppée, et la boucle passe à l'itération
suivante.
La boucledo while
ressemble
très fortement à la bouclewhile
, sauf que dans ce cas la boucle est
toujours exécutée au moins une fois. Dans le cas d'une bouclewhile
,
si la condition n'est pas valide, la boucle n'est pas exécutée. Avecdo
while
, la boucle est exécutée une première fois, puis la condition est testée pour savoir si la boucle
doit continuer.
Voici la syntaxe d'une
boucledo while
:
do {
instruction_1;
instruction_2;
instruction_3;
} while (condition);
On note donc une différence
fondamentale dans l'écriture par rapport à la bouclewhile
, ce qui
permet de bien faire la différence entre les deux. Cela dit, l'utilisation des
bouclesdo while
n'est pas très fréquente, et il est fort possible que
vous n'en ayez jamais l'utilité car généralement les programmeurs utilisent une
bouclewhile
normale, avec une condition qui fait que celle-ci est
toujours exécutée une fois.
La bouclefor
ressemble
dans son fonctionnement à la bouclewhile
, mais son architecture
paraît compliquée au premier abord. La bouclefor
est en réalité une
boucle qui fonctionne assez simplement, mais qui semble très complexe pour les débutants en raison de sa syntaxe.
Une fois que cette boucle est maîtrisée, il y a fort à parier que c'est celle-ci que vous utiliserez le plus
souvent.
Le schéma d'une
bouclefor
est le suivant :
for (initialisation; condition; incrémentation) {
instruction_1;
instruction_2;
instruction_3;
}
Dans les parenthèses de la boucle ne se trouve plus juste la condition, mais trois blocs : initialisation, condition, et incrémentation. Ces trois blocs sont séparés par un point-virgule ; c'est un peu comme si les parenthèses contenaient trois instructions distinctes.
for
, la boucle conçue pour
l'incrémentation
La bouclefor
possède
donc trois blocs qui la définissent. Le troisième est le bloc d'incrémentation qu'on va utiliser pour
incrémenter une variable à chaque itération de la boucle. De ce fait, la
bouclefor
est très pratique pour compter ainsi que pour répéter la
boucle un nombre défini de fois.
Dans l'exemple suivant, on va
afficher cinq fois une boîte de dialogue à l'aide dealert()
, qui
affichera le numéro de chaque itération :
for (var iter = 0; iter < 5; iter++) {
alert('Itération n°' + iter);
}
Dans le premier bloc, l'initialisation,
on initialise une variable appeléeiter
qui vaut 0 ; le
mot-clévar
est requis, comme pour toute initialisation. On définit
dans la condition que la boucle continue tant qu'iter
est
strictement inférieure à 5. Enfin, dans le bloc d'incrémentation, on indique
qu'iter
sera incrémentée à chaque itération terminée.
Mais il ne m'affiche que « Itération n°4 » à la fin, il n'y a pas d'itération n°5 ?
C'est tout à fait normal, pour
deux raisons : le premier tour de boucle porte l'indice 0, donc si on compte de 0 à 4, il y a bien 5 tours : 0, 1,
2, 3 et 4. Ensuite, l'incrémentation n'a pas lieu avant chaque itération, mais à la fin de chaque itération. Donc,
le tout premier tour de boucle est fait aveciter
qui vaut 0, avant
d'être incrémenté.
Avec les quelques points de théorie que nous venons de voir, nous
pouvons réécrire notre exemple des prénoms, tout en montrant qu'une bouclefor
peut
être utilisée sans incrémentation :
for (var nicks = '', nick; true;) {
nick = prompt('Entrez un prénom :');
if (nick) {
nicks += nick + ' ';
} else {
break;
}
}
alert(nicks);
Dans le bloc d'initialisation
(le premier), on commence par initialiser nos deux variables. Vient alors le bloc avec la condition (le
deuxième), qui vaut simplementtrue
. On termine par le bloc d'incrémentation
et… il n'y en a pas besoin ici, puisqu'il n'y a pas besoin d'incrémenter. On le fera pour un autre exemple juste
après. Ce troisième bloc est vide, mais est requis. C'est pour cela que l'on doit quand même mettre le point-virgule
après le deuxième bloc (la condition).
Maintenant, modifions
la boucle de manière à compter combien de prénoms ont été enregistrés. Pour ce faire, nous allons créer une variable
de boucle, nomméei
, qui sera incrémentée à chaque passage de boucle.
for (var i = 0, nicks = '', nick; true; i++) {
nick = prompt('Entrez un prénom :');
if (nick) {
nicks += nick + ' ';
} else {
break;
}
}
alert('Il y a ' + i + ' prénoms :\n\n' + nicks);
La variable de boucle a été ajoutée
dans le bloc d'initialisation. Le bloc d'incrémentation a lui aussi été modifié : on indique qu'il
faut incrémenter la variable de bouclei
. Ainsi, à chaque passage dans
la boucle,i
est incrémentée, ce qui va nous permettre de compter assez
facilement le nombre de prénoms ajoutés.
En JavaScript, il est déconseillé de déclarer des variables au sein
d'une boucle (entre les accolades), pour une raison logique : il n'y a en effet pas besoin de déclarer une même
variable à chaque passage dans la boucle ! Il est conseillé de déclarer les variables directement dans le bloc
d'initialisation, comme montré dans les exemples de ce cours. Mais attention : une fois que la boucle est
exécutée, la variable existe toujours, ce qui explique que dans l'exemple précédent on puisse récupérer la valeur dei
une
fois la boucle terminée. Ce comportement est différent de celui de nombreux autres langages, dans lesquels une
variable déclarée dans une boucle est « détruite » une fois la boucle exécutée.
Les trois blocs qui constituent la
bouclefor
ne sont pas exécutés en même temps :
Initialisation
: juste avant que la boucle ne démarre. C'est comme si les instructions d'initialisation avaient été écrites
juste avant la boucle, un peu comme pour une bouclewhile
;
Condition : avant chaque passage de boucle, exactement comme la condition d'une
bouclewhile
;
Incrémentation :
après chaque passage de boucle. Cela veut dire que, si vous faites unbreak
dans
une bouclefor
, le passage dans la boucle lors
dubreak
ne sera pas comptabilisé.
La bouclefor
est
très utilisée en JavaScript, bien plus que la bouclewhile
. Comme nous
le verrons par la suite, le fonctionnement même du JavaScript fait que la
bouclefor
est nécessaire dans la majorité des cas comme la
manipulation des tableaux ainsi que des objets. Ce sera vu plus tard. Nous verrons aussi une variante de la
bouclefor
, appeléefor
in
, mais que nous ne pouvons aborder maintenant car elle ne s'utilise que dans certains cas spécifiques.
L'incrémentation est importante au sein des boucles. Incrémenter ou décrémenter signifie ajouter ou soustraire une unité à une variable. Le comportement d'un opérateur d'incrémentation est différent s'il se place avant ou après la variable.
La
bouclewhile
permet de répéter une liste d'instructions tant que la
condition est vérifiée.
La
boucledo while
est une variante
dewhile
qui sera exécutée au moins une fois, peu importe la
condition.
La
bouclefor
est une boucle utilisée pour répéter une liste
d'instructions un certain nombre de fois. C'est donc une variante très ciblée de la
bouclewhile
.