Uwaga! Trwają prace nad nową wersją serwisu. Mogą występować przejściowe problemy z jego funkcjonowaniem. Przepraszam za niedogodności!

⛔ Potrzebujesz wsparcia? Oceny CV? A może Code Review? ✅ Dołącz do naszej społeczności na Discordzie!

Pętla for...of i pętla for...in – różnica

Iterowanie po elementach tablicy i obiektu

Pętle for...in i for...of są używane do iterowania po różnych typach danych, ale mają nieco inne zastosowania. W tym artykule omówię obie pętle, pokażę przykłady ich użycia i podsumuję różnice działania.

Spis treści

 Pętla for...of

Pętla for...of w JavaScripcie jest używana do iterowania po takich strukturach danych jak tablice, ciągi znaków, Nodelist, Set czy Map. Mówi się o nich, że są iterowalne (implementują iterable protocol). Pętla for...of przechodzi przez każdy zawarty w nich element i wykonuje na nim operacje zadeklarowane w kodzie ciała pętli.

 Pętla for...of dla tablicy

Pętlę tę będziesz najczęściej stosować właśnie dla tablic, więc najpierw omówimy ten przykład. Powiedzmy, że chcemy wyświetlić nazwy owoców, ale zapisane małymi literami:

const fruits = ["APPLE", "BANANA", "LEMON", "ORANGE", "PEAR"];
// zmienna 'fruit' (możemy ją nazwać dowolnie) przy każdej iteracji pętli będzie zawierała kolejny owoc, czyli "APPLE", "BANANA", "LEMON" itd.
for (const fruit of fruits) {
  const lowerCasedFruit = fruit.toLowerCase(); // zmieniamy litery owocu na małe 
  console.log(lowerCasedFruit); // wyświetlamy efekt w konsoli
}

W tym przykładzie iterujemy przez elementy tablicy fruits i na każdym z nich wykonujemy wybraną operację (tutaj akurat zamieniamy litery na małe), a następnie wyświetlamy go w konsoli.

Uwaga: pętla for...of przechodzi przez elementy struktury (tu: tablicy) zgodnie z kolejnością indeksów.

 Pętla for...of dla stringa, NodeList, Set czy Map

String

Czy wiesz, że znaki w stringu mają tak naprawdę swoje indeksy (jak elementy tablicy)? Na ciągu znaków też można wykonać pętlę for...of!

Powiedzmy, że chcemy do każdej litery dodać spację. Możemy to zrobić np. w ten sposób:

const myString = 'Hello world';
let modifiedString = ''; // tutaj zapiszę wynik po każdej iteracji pętli

for (const character of myString) {
  modifiedString += character + ' '; // za każdą iteracją mój nowy string otrzymuje kolejne litery ze spacją. Podejrzysz to tutaj (odkomentuj kod):
// console.log(modifiedString)
}

console.log(modifiedString); // ostateczny wynik działania pętli

NodeList

Kolekcję węzłów otrzymamy na przykład wtedy, gdy wyszukamy elementy w drzewie DOM za pomocą metody .querySelectorAll().

<ul>
  <li>item1</li>
  <li>item2</li>
  <li>item3</li>
</ul>
// wyszukuję wszystkie elementy li występujące w drzewie DOM
const liElements = document.querySelectorAll("li");

for (const liItem of liElements) {
  console.log(liItem.innerText) // wyświetlam tekst zawarty w elemencie li
}

Set i Map

Jeżeli nie kojarzysz tych elementów, możesz się z nimi zapoznać np. na stronie kursu JavaScript. Prawdopodobnie nie będziesz z nich często korzystać, lecz warto wiedzieć, że pętla for...of również w ich przypadku działa.

// Przykład dla Set
const mySet = new Set(['a', 'b', 'c', 'c']);
for (const item of mySet) {
  console.log(item);
}
// Przykład dla Map
const myMap = new Map([[1, 'one'], [2, 'two'], [3, 'three']]);
for (const element of myMap) {
  console.log(element[1]);
}

 Pętla for...in

Pętla for...in jest używana do iterowania po właściwościach obiektu w JavaScript. Przechodzi ona przez każdą właściwość obiektu i wykonuje na niej operacje zdefiniowane w ciele pętli.

Najpierw prosty przykład, w którym tylko wyświetlimy efekt działania pętli w konsoli. Iterujemy po obiekcie person:

const person = {
  name: "Jan",
  age: 30,
  occupation: "Developer"
};

for (const key in person) {
  // zauważ, że zmienna 'key' (możemy nazwać ją dowolnie) przechowuje nazwy właściwości, czyli klucze 
  console.log(key); // efekt kolejnych iteracji: "name", "age","occupation"
}

Zwróć uwagę, że zmienna key (nazwa jest dowolna, możemy np. nazwać ją element czy prop) przechowuje nazwę właściwości (klucz). Jeżeli więc chcemy mieć dostęp do przypisanej do niej wartości, musimy skorzystać z zapisu obiekt["nazwa właściwości"], np. person["name"].

W naszym kodzie będzie wyglądało to w ten sposób:

const person = {
  name: "Jan",
  age: 30,
  occupation: "Developer"
};

for (const key in person) {
  const value = person[key] // przy każdej iteracji zostanie zamienione to na: person["name"], person["age"] itd.
  console.log("This person " + key + " is " + value);
}
Uwaga: pętla for...in iteruje przez właściwości obiektu w kolejności zależnej od implementacji ECMAScript w silniku przeglądarki (zawsze bierz to pod uwagę, nawet jeśli w Twojej ocenie kolejność wyników zostaje zachowana).

 Różnica między pętlą for...of i for...in

Podstawowa różnica między pętlą for...in a for...of polega na tym, że pętla for...in iteruje przez właściwości obiektu, podczas gdy pętla for...of iteruje przez elementy tzw. obiektów iterowalnych, czyli tablic, stringów, NodeList, Set, Map itd.

Druga różnica to ta zamieszczona w ramkach z uwagami: pętla for...of iteruje po elementach w kolejności zgodnej z numerami indeksów, natomiast w obiektach pętla for...in może kolejności nie zachowywać (zależy to od implementacji EcmaScript w przeglądarce).

Pętle for...in i for...of są powszechnie używane w praktyce – z powodzeniem zastępują znaną Ci już pewnie pętlę for. Zachęcam do dalszej nauki i eksperymentowania z różnymi rodzajami struktur danych i pętli w JavaScript!

Udostępnij ten artykuł:

Mentoring to efektywna nauka pod okiem doświadczonej osoby, która:

  • przekazuje Ci swoją wiedzę i nadzoruje Twoje postępy w zdobywaniu umiejętności,
  • uczy Cię dobrych praktyk i wyłapuje złe nawyki,
  • wspiera Twój rozwój i zwiększa zaangażowanie w naukę.

Mam coś dla Ciebie!

W każdy piątek rozsyłam motywujący do nauki programowania newsletter!

Dodatkowo od razu otrzymasz ode mnie e-book o wartości 39 zł. To ponad 40 stron konkretów o nauce programowania i pracy w IT.

PS Zazwyczaj wysyłam 1-2 wiadomości na tydzień. Nikomu nie będę udostępniał Twojego adresu e-mail.