Jak zmienna pętli for tak naprawdę działa

0

Jak to jest, że zmienna var nie nadpisuje poprzednich wartości wewnątrz pętli for. Wiem że tak się dzieje kiedy wewnątrz pętli znajdzie się funkcja, wtedy należy użyć let zamiast var lub opakować wszystko funkcją anonimową. Poniżej znajduje się prosty przykład:

for (var a=0; a<10; a++) {
  console.log(a);
}

W konsoli wypisuje liczby od 0-9, ale moim rozumowaniem kiedy var jest zmienną o zasięgu funkcyjnym, zmienna a powinna nadpisać poprzednie wartości i wypisać do konsoli 9 razy tą samą liczbę czyli 9. Więc jak dokładnie działa ta pętla.

0

bo jest nadpisywana.

1

Trochę za dużo wiedzy łykasz jak na początek i robi Ci się woda z mózgu :D
Zacznijmy od struktury pętli for.

for(var i=0, j=5, k=10; // inicjujemy wstępne wartości
	i<5; // stawiamy warunek do kiedy pętla ma się wykonywać
	i++, j*=2, k+=2) // ustalamy w jaki sposób zainicjowane wartości mają się zwiększać
	console.log('i=' + i, 'j=' + j, 'k=' + k)

Przykład:

var i = 3;
console.log('pierwsze przypisanie: ' + i)

for(var i=0; i<5; i++)
   console.log('wartosc w petli: ' + i)

console.log('wartosc po wyjsciu z petli: ' + i)

var i = 5;
console.log('przypisanie nowej wartosci: ' + i)

'pierwsze przypisanie: 3'
'wartosc w petli: 0'
'wartosc w petli: 1'
'wartosc w petli: 2'
'wartosc w petli: 3'
'wartosc w petli: 4'
'wartosc po wyjsciu z petli: 5' // dlaczego? inkrementacja z petli "i++" musiała się wykonać zanim warunek został sprawdzony
'przypisanie nowej wartosci: 5'

Jeżeli przypisujesz wartości do zmiennych zaczynając od "var", to wszystkie poprzednie zmienne o takiej nazwie, zresztą jak wspomniał przedmówca, zostaną nadpisane. Możesz sobie troszkę zmodyfikować powyższy przykład i pominąć nadpisywanie zmiennej i - "for(; i<5; i++)", sprawdzić co się stanie i pobawić się zasięgiem zmiennych :P

2

Akurat pokazałeś przykład gdzie wszystko jest proste. Weźmy na tapet coś takiego:

for (var a = 0; a < 10; a++) {
    setTimeout(function() { console.log(a) }, a * 100);
}

Zamiast wypisać ciąg od 0 do 9 to 10 razy wypisze się 10. Dlaczego? Dlatego, że nie ma tutaj żadnego kopiowania aktualnej zawartości zmiennej a do późniejszego wykorzystania. Jedyne co jest to domknięcie się na referencji do a, a więc do świeżej zawartości tej zmiennej. Pętla kończy się zanim funkcja przekazana do setTimeout się wykonuje, więc console.log loguje wartość a po zakończeniu pętli.

W zrozumieniu domknięć w JavaScripcie może pomóc klasyczny zapis do enkapsulacji pól:

function Rocket() {
  var fuel = 100;

  return {
    getFuel: function() { return fuel; },
    setFuel: function(value) { fuel = value; }
  };
}

Mimo iż fuel wychodzi poza zasięg podczas powrotu z funkcji Rocket to getter i setter poprawnie działają i mają dostęp do świeżej zawartości zmienej fuel a nie kopii zrobionej raz w którymś momencie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1