Am văzut până acum că, dacă dorim să executăm aceleași instrucțiuni de mai multe ori, fie le scriem de mai multe ori, fie creăm o funcție și o apelăm de mai multe ori. În cazul funcțiilor, am văzut că putem avea parametri astfel încât am putea avea variații asupra modului în care se execută instrucțiunile din corpul funcției.
Dar, aceste soluții au un impediment. Trebuie să știm exact de câte ori vrem să executăm acele instrucțiuni și fie să le scriem de atâtea ori, fie să apelăm de atâtea ori o funcție care le conține. Ce facem dacă nu știm exact de câte ori vrem să fie executate?
De exemplu, am putea dori să scriem cifrele unui număr. Vom avea, probabil, o instrucțiune care va scrie o cifră și un mecanism prin care acesta va fi apelată. Dar, în funcție de cât de mare este acel număr, numărul execuțiilor va varia. Pentru numărul 2457 instrucțiunea se va executa de patru ori, dar pentru 47 doar de două ori.
Am văzut în episodul VIII că pentru a determina ultima cifră a unui număr este suficient să calculăm restul împărțirii acelui număr la zece. Putem observa că, practic, printr-o împărțire întreagă (calcularea câtului împărțirii) la zece eliminăm acea cifră din număr. Restul împărțirii noului număr la zece ne va da penultima cifră a numărului inițial; o nouă împărțire întreagă la zece va elimina și această cifră. Continuăm până se termină cifrele, adică atâta timp cât rezultatul împărțirii la zece va fi mai mare decât zero.
În JavaScript nu există un operator pentru împărțirea întreagă. Pentru a simula "eliminarea" ultimei cifre vom scădea acea cifră din număr (în urma scăderii vom obține un multiplu de zece) și apoi vom împărți rezultatul la zece.
Vom avea cifrele în ordine inversă, dar ne vom mulțumi cu acest lucru deocamdată; de asemenea, nu va funcționa pentru numere negative și nici pentru numărul zero (vom crede că nu există nicio cifră).
Limbajul JavaScript ne pune la dispoziție o construcție care permite executarea unei instrucțiuni atâta timp cât o anumită condiție este adevărată. Evident, instrucțiunea respectivă poate fi un bloc de instrucțiuni. La fel ca în cazul instrucțiunii if (a se vedea episodul IV) se păstrează recomandarea de a avea un bloc format dintr-o singură instrucțiune în locul unei instrucțiuni simple.
Instrucțiunea while
Dar, care este noua instrucțiune? Pentru a explica ce vrem să facem, am folosit cuvintele atâta timp; am spus că atâta timp cât o anumită condiție este îndeplinită vom efectua o anumită acțiune. Și în JavaScript vom folosi ceva similar; va fi în engleză, deci cuvântul va fi while. El va fi urmat de condiția care trebuie verificată, cuprinsă între paranteze rotunde și apoi de instrucțiunea care trebuie executată cât timp condiția este îndeplinită. Condiția este o expresie booleană; poate fi o simplă variabilă sau o expresie mai complexă. O astfel de instrucțiune este numită iterativă. Mai sunt folosite și denumirile de instrucțiune repetitivă sau buclă. Instrucțiunile executate atâta timp cât este îndeplinită condiția sunt numite și corpul buclei.
Putem scrie acum secvența care afișează cifrele unui număr (în ordine inversă)...
1 2 3 4 5 |
var n = 2457 while (n > 0) { document.writeln(n % 10) n = (n - n % 10) / 10 } |
Astfel de instrucțiuni pot apărea oriunde; de exemplu, ar putea fi parte a unui bloc de instrucțiuni (în interiorul unui alt while, al unui if, al unei funcții etc.). Să vedem cum facem o funcție care să afișeze cifrele unui număr:
1 2 3 4 5 6 |
function cifre(n) { while (n > 0) { document.writeln(n % 10) n = (n - n % 10) / 10 } } |
Observăm că este posibil ca blocul de instrucțiuni care formează bucla să nu se execute niciodată în cazul în care condiția nu este îndeplinită la prima verificare. Acest lucru s-ar întâmpla dacă am apela funcția de mai sus transmițând ca argument un număr negativ sau zero.
De asemenea, trebuie să avem în vedere că în corpul buclei trebuie să existe la un moment dat ceva care afectează condiția care este evaluată. Altfel, aceasta va rămâne tot timpul adevărată (dacă a fost prima dată) și corpul său se va executa la infinit dacă nu este înterupt prin alt mecanisme (de exemplu printr-un return).
While în while
Am spus că instrucțiunea while poate apărea oriunde. De exemplu, ar putea fi parte a blocului de instrucțiuni al unei alte instrucțiuni while. Să încercăm să scriem un program care afișează tabla înmulțirii până la zece. Vom avea numerele de la unu la zece ca prim factor și, pentru fiecare dintre acestea, numerele de la unu la zece ca al doilea factor. Să vedem cum ar arăta o funcție care ar realiza acest lucru:
1 2 3 4 5 6 7 8 9 10 11 12 |
function tablaInmultirii() { var factor1 = 1 while (factor1 <= 10) { var factor2 = 1 while (factor2 <= 10) { document.writeln(factor1 * factor2) factor2++ } document.writeln("<br/>") factor1++ } } |
Valorile nu sunt aliniate foarte frumos, dar nu vom insista acuma asupra acestui aspect. Dacă este apelată funcția de mai sus, vom obține ceva de genul:
1 2 3 4 5 6 7 8 9 10 |
1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20 24 28 32 36 40 5 10 15 20 25 30 35 40 45 50 6 12 18 24 30 36 42 48 54 60 7 14 21 28 35 42 49 56 63 70 8 16 24 32 40 48 56 64 72 80 9 18 27 36 45 54 63 72 81 90 10 20 30 40 50 60 70 80 90 100 |
Instrucțiunea do while
Până acum secvențele noastre erau de genul: cât timp o anumită condiție este îndeplinită execută instrucțiunile următoare. Avem la dispoziție o variație: execută instrucțiunile următoare cât timp o anumită condiție este îndeplinită.
În noua variantă, executăm instrucțiunile și abia apoi verificăm dacă este îndeplinită condiția. Dacă este îndeplinită mai executăm odată instrucțiunile și tot așa cât timp este îndeplinită acea condiție. Observăm că în această situație vom executa corpul buclei cel puțin odată.
Noua instrucțiune începe cu do, urmat de instrucțiunea sau blocul de instrucțiuni care formează corpul buclei, de cuvântul while și de condiția care trebuie verificată la sfârșit, între paranteze. Să rescriem funcția care afișează cifrele unui număr:
1 2 3 4 5 6 |
function cifre(n) { do { document.writeln(n % 10) n = (n - n % 10) / 10 } while (n > 0) } |
Observăm un efect interesant; datorită faptului că se va executa cel puțin odată corpul buclei, de data aceasta vom avea rezultatul corect și dacă apelăm funcția cu argumentul zero.
Va urma
În episodul următor vom prezenta o altă instrucțiune repetitivă care simplifică puțin codul în anumite situații.