Loops and iteration

This translation is incomplete. Please help translate this article from English.

Loops (bucle in romana) sunt o modalitate de a face ceva in mod repetat. Acest capitol din Ghidul Javascript este o prezentare a modalitatilor diferite in care putem declara instructiuni repetate (iteration statement) in JavaScript.

Ne putem gandi la un loop ca la o versiune computerizata a unui joc in care ii spunem cuiva sa mearga un anumit numar de pasi intr-o directie apoi un anumit numar de pasi in alta directie. De exemplu "Fa 5 pasi la stanga" poate fi exprimata in acest mod printr-un loop:

var pasi;
for (pasi = 0; pasi < 5; pasi++) {
  // Executa de 5 ori aplicand variabilei pasi valori de la 0 pana la 4.
  console.log('Fa cate un pas la stanga');
}

Exista mai multe tipuri de bucle (loops) dar toate au acelasi scop: a repeta o actiune ori de cate ori este specificat (e posibil chiar ca numarul de repetitii specificat sa fie 0). Diferenta dintre tipurile de bucle consta in modalitatea in care sunt determinate punctele de start si de stop. Alegerea tipului de loop depinde de situatie, unele sunt mai potrivite decat altele cum o sa vedem in continuare.

Instructiunile pentru bucle (loop statement) disponibile in JavaScript sunt urmatoarele:

for statement

Aceasta instructiune for loop se repeta pana cand conditia specificata rezulta falsa (false). Pentru cine cunoaste Java sau C aceasta instructiune este asemenatoare. In continuare sa analizam un exemplu:

for ([initialExpression]; [condition]; [incrementExpression])
  statement

Cand acest tip de bucla - for loop - este executata se intampla urmatoarele:

  1. Mai intai expresia declansatoare initialExpression - daca exista - este executata. Aceasta expresie declanseaza de obicei una sau mai multe bucle sintaxa permitand orice nivel de complexitate. Poate declara si variabile.
  2. Apoi conditia (condition) este evaluata. Daca valoarea conditiei este adevarata (true) intructiunea buclei (loop statement) este executata. In caz contrar, daca returneaza false, bucla este stopata. Exista cazuri in care conditia este omisa, atunci se presupune ca nefiind nici o conditie, rezultatul este true.
  3. Dupa care instructiunea (statement) este executata. Pentru a executa mai multe instructiuni se foloseste un bloc de instructiuni ({ ... }) pentru a le grupa impreuna.
  4. In cele din urma expresia incrementExpression - daca exista - este executata si bucla se repeta de la pasul 2;

Exemplu

Functia urmatoare contine o instructie de tipul for statement care numara cate optiuni au fost selectate dintr-o lista scroll  (un <select> element care permite mai multe selectii). Instructiunea for statement declara variabila i care are startul la 0. Verifica ca i sa fie ai mic decat numarul de optiuni din elementul <select>, declanseaza urmatoarea instructiune if statement si incrementeaza i cu unul la fiecare repetare a buclei.

<form name="selectForm">
  <p>
    <label for="musicTypes">Alege genul de muzica preferat si apasa pe buton</label>
    <select id="musicTypes" name="musicTypes" multiple="multiple">
      <option selected="selected">R&B</option>
      <option>Jazz</option>
      <option>Blues</option>
      <option>New Age</option>
      <option>Clasica</option>
      <option>Opera</option>
    </select>
  </p>
  <p><input id="btn" type="button" value="Cate genuri selectionate?" /></p>
</form>

<script>
function cateGenuri(selectObject) {
  var numberSelected = 0;
  for (var i = 0; i < selectObject.options.length; i++) {
    if (selectObject.options[i].selected) {
      numberSelected++;
    }
  }
  return numberSelected;
}

var btn = document.getElementById('btn');
btn.addEventListener('click', function() {
  alert('Numarul de genuri selectionate: ' + cateGenuri(document.selectForm.musicTypes));
});
</script>

do...while statement

Instructiunea  do...while se repeta pana cand o conditie specifica returneaza false. O insctructiune do...while arata in felul urmator:

do
  statement
while (condition);

statement (instructia) se executa o data cand canditia este verificata. Pentru a executa mai multe instructiuni se foloseste blocul de instructiuni  ({ ... }) pentru a le grupa impreuna. Daca conditia (condition) returneaza true instructiunea este executata din nou. La sfarsitul fiecarei executii conditia este verificata. Cand conditia returneaza false se stopeaza iar controlul este trecut instructiei urmatoare do...while.

Exemplu

In urmatorul exemplu bucla do se repeta cel putin odata apoi se repeta pana cand variabila i nu mai este mai mica decat 5.

var i = 0;
do {
  i += 1;
  console.log(i);
} while (i < 5);

while statement

Instructiunea while se executa pana cand conditia returneaza true. Instructiunea while arata in felul urmator:

while (condition)
  statement

Cand conditia devine false instructiunea (statement) din bucla (loop) se stopeaza iar controlul trece la instructiunea care urmeaza buclei.

Verificarea conditiei are loc inainte ca intructiunea (statement) din bucla sa fie executata. Daca conditia returneaza true instructiunea (statement) este executata iar conditia este verificata din nou. Daca conditia returneaza false executia se stopeaza iar controlul trece la instructiunea (statement) care urmeaza while.

Pentru a executa mai multe instructiuni (statement) se foloseste un bloc de instructiuni ({ ... }) pentru a le grupa impreuna.

Exemplul 1

Urmatoarea bucla while se va repeta pana cand variabila n va fi mai mica decat trei:

var n = 0;
var x = 0;
while (n < 3) {
  n++;
  x += n;
}

Cu fiecare repetare bucla incrementeaza n si adauga valoarea lui x. Astfel x si n vor avea urmaoarele valori:

  • Dupa prima repetitie: n = 1 and x = 1
  • Dupa a doua repetitie: n = 2 and x = 3
  • Dupa a treia repetitie: n = 3 and x = 6

Dupa completarea celei de-a treia repetitii, conditia n < 3 nu mai este true deci bucla este stopata.

Exemplul 2

Evitati buclele infinite. Aveti grija specificati o conditie care eventual sa devina false altfel bucla nu se va termina niciodata. Instructiunile specificate in urmatorea bucla vor fi executate la nesfarsit pentru ca nu este specificata nici o conditie care sa devina false:

while (true) {
  console.log('Hello, world!');
}

labeled statement

O bucla label furnizeaza o instructiune cu un identificator (eticheta) care poate fi folosit ca referinta in alta parte a programului. Spre exemplu se poate utiliza o eticheta pentru a identifica o bucla, apoi se poat folosi instructiuni break or continue pentru a specifica daca bucla trebuie intrerupta sau continuata.

Sintaxa pentru o instructiune cu eticheta (labeled statement) arata in felul urmator:

label : statement

Valoarea etichetei label poate fi orice identificator JavaScript atata timp cat nu este un cuvant rezervat. Instructiunea (statement) etichetata astfel poate fi orice instructiune.

Exemplu

In acest exemplu buclaCuEticheta identifica o bucla while.

buclaCuEticheta:
while (oEticheta == true) {
   doSomething();
}

break statement

Folositi instructiunea break pentru a stopa o bucla, switch sau in combinatie cu o instructiune label.

  • Daca se foloseste instructiunea break fara o eticheta (label) va stopa imediat cea mai apropiata bucla while, do while, for sau switch si va transfera controlul instructiei urmatoare.
  • Daca se foloseste break cu eticheta (label) va stopa instructiunea etichetata (labeled statement).

Sintaxa instructiunii break arata asfel:

break [label];

In continuare o sa vedem doua exemple. Prima sintaxa nu are o eticheta deci va stopa cea mai apropiata bucla (loop) sau comutator (switch). A doua sintaxa va identifica si va stopa bucla etichetata.

Exemplul 1: Intreruperea celei mai apropiate bucle

In urmatorul exemplu bucla se repeta prin elementele unui array pana cand va gasi indexul unui element a carui valoare este theValue:

for (var i = 0; i < a.length; i++) {
  if (a[i] == theValue) {
    break;
  }
}

Exemplul 2: Intreruperea unei bucle etichetate

var x = 0;
var z = 0;
labelCancelLoops: while (true) {
  console.log('Outer loops: ' + x);
  x += 1;
  z = 1;
  while (true) {
    console.log('Inner loops: ' + z);
    z += 1;
    if (z === 10 && x === 10) {
      break labelCancelLoops;
    } else if (z === 10) {
      break;
    }
  }
}

continue statement

Instructiunea continue este folosita pentru a reporni instructiuni while, do-while, for, or label.

  • Cand se foloseste o instructiune continue fara o eticheta aceasta va stopa repetarea curenta cea mai apropiata a instructiunilor  while, do-while sau for si va continua executia buclei cu urmatoarea repetare. Spre deosebire de break, continue nu stopeaza repetitia intregii bucle. Intr-o bucla while va sari inapoi la conditie. Intr-o bucla for va sari la incrementare (increment-expression).
  • Cand este folosita cu o eticheta se va aplica buclei identificata cu acea eticheta.

Sintaxa instructiunii continue arata astfel:

continue [label];

Exemplul 1

Urmatorul exemplu demonstreaza cum o bucla while cu o instructiune continue este executata can valoarea lui i este trei. Prin urmare n va asuma valorile unu, trei, sapte si doisprezece.

var i = 0;
var n = 0;
while (i < 5) {
  i++;
  if (i == 3) {
    continue;
  }
  n += i;
}

Exemplul 2

O instructiune etichetata verificaXsiY contine o instructiune etichetata verificaY. Daca va intalni continue programul va stopa repetitia curenta a verificaY si va incepe urmatoarea repetitie. De fiecare daca cand va intalni continue verificaY se repeta pana cand conditia va returna false. Cand false este returnat restul instructiunii verificaXsiY va fi completat si verificaXsiY se va repeta pana cand conditia de repetare va returna false. Cand va returna false programul va continua instructiunile de dupa verificaXsiY.

Daca continue are eticheta verificaXsiY atunci programul va continua la inceputul instructiunii verificaXsiY.

verificaXsiY:
  while (X < 4) {
    console.log(X);
    X += 1;
    checkY:
      while (Y > 4) {
        console.log(Y);
        Y -= 1;
        if ((Y % 2) == 0) {
          continue checkY;
        }
        console.log(Y + ' is odd.');
      }
      console.log('X = ' + X);
      console.log('Y = ' + Y);
  }

for...in statement

O instructie  for...in repeta o variabila specifica peste toate proprietatile enumerabile ale unui obiect. Pentru fiecare obiect distinct JavaScript executa o instructie specifica. O instructie de tipul for...in statement arata in felul urmator:

for (variable in object) {
  statements
}

Exemplu

Urmatoarea functie are ca argument un obiect si numele obiectului. Se repeta peste toate proprietatile obiectului si returneaza un sir (string) care enumera numele proprietatii si valoarea acesteia.

function dump_props(obj, obj_name) {
  var result = '';
  for (var i in obj) {
    result += obj_name + '.' + i + ' = ' + obj[i] + '<br>';
  }
  result += '<hr>';
  return result;
}

In cazul unui obiect cu numele masina cu proprietatile marca si model, resultatul va fi:

masina.marca = Ford
masina.model = Mustang

Arrays

Cu toate ca ar fi tentant sa folosim aceasta metoda pentru a efectua o repetitie peste elementele Array, instructiunea for...in va returna numele proprietatilor definite de utilizator impreuna cu indexul numeric. Prin urmare este mai bine sa folosim traditionalul loop for impreuna cu un index numeric cand efectuam repetitia peste array, pentru ca instructiunea for...in se va repeta peste proprietatile definite de catre user impreuna cu elementele array-ului cuprinzand noile proprietati in cazul in care se modifica obiectul array-ului precum adaugarea de proprietati personalizate sau metode.

for...of statement

O instructiune for...of creaza o bucla repetand peste obiectele repetibile (incluzand ArrayMap, Set, arguments obiecte si asa mai departe), evocand o repetitie personalizata legata de o instructie de executat pentru valoarea distincta a fiecarei proprietati.

for (variable of object) {
  statement
}

Urmatorul exemplu demonstreaza diferenta dintre for...of loop si for...in loop. In timp ce for...in se repeta peste numele proprietatilor, for...of se repeta peste numele acestora:

let arr = [3, 5, 7];
arr.foo = 'hello';

for (let i in arr) {
   console.log(i); // logs "0", "1", "2", "foo"
}

for (let i of arr) {
   console.log(i); // logs 3, 5, 7
}

Document Tags and Contributors

 Contributors to this page: zorax
 Last updated by: zorax,