Menu

JavaScript for...of ve for...in: Dizi ve Nesne Döngüsü

JavaScript'te for...of ve for...in arasındaki fark tam olarak nedir? Değer mi anahtar mı, dizi mi nesne mi, hangisini ne zaman kullanmalı?

İki döngü, iki farklı iş

JavaScript'te neredeyse aynı görünen ama bambaşka işler yapan iki döngü var. for...of bir iterable'ın değerleri üzerinde gezinir. for...in ise bir nesnenin anahtarları üzerinde gezinir. Tek harf fark, ama davranış tamamen farklı.

Tüm hikâyeyi tek bir örnekte görelim:

index.js
Output
Click Run to see the output here.

İlk döngü apple, banana, cherry yazdırır — yani değerleri. İkincisi ise 0, 1, 2 yazdırır — yani anahtarları, hem de string olarak. Yanlışını seçersen, dizinin neden sayılarla dolu olduğunu anlamaya çalışarak on dakika harcarsın.

for...of: Iterable olan her şeyden değer almak

for...of, günlük hayatta en sık uzanacağın döngüdür. JavaScript'in iterable saydığı her şeyde çalışır: diziler, stringler, Map, Set, NodeList, generator'lar ve dahası.

index.js
Output
Click Run to see the output here.

İndeksle uğraşmak yok, scores[i] yazmana gerek yok. Her değeri istersin, her değeri alırsın. String'ler de iterable olduğu için for...of onları karakter karakter gezer:

index.js
Output
Click Run to see the output here.

Bu yöntem, çoğu Unicode karakteriyle de sorunsuz çalışıyor; string'e sayısal index'le erişmeye kıyasla küçük ama gerçek bir avantaj.

for...of ile Index Alma

for...of döngüsünün sana doğrudan vermediği tek şey elemanın sırası. Index'e ihtiyacın olduğunda entries() ile birlikte kullanman yeterli:

index.js
Output
Click Run to see the output here.

names.entries() sana [index, value] şeklinde çiftler döndürür; baştaki destructuring de bunları iki ayrı değişkene ayırır. Sırf i'ye ihtiyacın var diye klasik for (let i = 0; ...) yazmaktan genelde çok daha temiz bir yoldur.

for...in: Nesnenin Anahtarları Üzerinde Döngü

for...in, düz nesneler için tasarlanmıştır. Nesnenin enumerable string anahtarları üzerinde döner:

index.js
Output
Click Run to see the output here.

Dikkat: burada değeri değil, anahtarı (key) alırsın. Değere erişmek için user[key] şeklinde tekrar nesneye girmen gerekir. Ayrıca her anahtar bir string'dir — sayı gibi görünse bile.

for...in prototip zincirini de dolaştığı için miras alınan özellikleri de önüne getirebilir. Kendi yazdığın literal nesnelerde bu pek sorun olmaz; ama bir sınıfın örnekleri ya da bir kütüphaneden gelen nesneler üzerinde döngü kurarken temkinli olmakta fayda var:

index.js
Output
Click Run to see the output here.

Object.hasOwn(user, key) kalıtım yoluyla gelen özellikleri es geçer. Modern kodda çoğu geliştirici for...in kullanmaktan tamamen kaçınıyor; onun yerine Object.keys, Object.values veya Object.entries tercih ediliyor — ki bu da bizi bir sonraki bölüme getiriyor.

JavaScript'te Nesne Üzerinde Döngü Kurmanın Modern Yolu

for...in yerine for...of döngüsünü Object.* yardımcılarından biriyle birleştirmek çok daha yaygın bir yaklaşım. İhtiyacına göre bu üçünden birini seçiyorsun:

index.js
Output
Click Run to see the output here.

Object.entries burada gerçekten çok işe yarıyor — [key, value] çiftini destructuring ile açtığınızda kod neredeyse düz cümle gibi okunuyor. Üstelik bu metotlar yalnızca nesnenin kendi enumerable özelliklerini döndürdüğü için, prototip zincirinden sızan gereksiz şeylerle uğraşmak zorunda kalmazsınız.

Dizilerde for...in Kullanmayın

Teknik olarak çalışıyor, evet — ama insanları tökezleten klasik bir tuzak:

index.js
Output
Click Run to see the output here.

0, 1, 2 derken tag de geliyor. Birinin diziye eklediği herhangi bir property — ya da polyfill üzerinden Array.prototype'a iliştirilen her şey — karşına çıkar. Üstüne anahtarlar string olduğu için key + 1 toplama yapmaz, stringleri birleştirir. Bir de iterasyon sırasının her edge case'te dizi sırasıyla eşleşeceğinin garantisi yok.

Pratik kural:

  • Dizinin değerleri mi lazım? for...of arr.
  • Hem index hem değer mi lazım? for...of arr.entries().
  • Sadece index ile sayaç mı tutacaksın? Klasik for (let i = 0; i < arr.length; i++).
  • Nesnenin anahtarları ya da entry'leri mi? Object.keys(obj) / Object.entries(obj) ile birlikte for...of.

Kısacası: for...in oldukça niş bir araç. for...of ile Object yardımcılarını birleştirince ihtiyacın olan her şeyi karşılıyorsun.

break ve continue Her İkisinde de Çalışır

Her iki döngü de bildiğimiz erken çıkış araçlarını destekler:

index.js
Output
Click Run to see the output here.

continue bir sonraki iterasyona atlar; break ise döngüden tamamen çıkar. Zaten for...of döngüsünü .forEach() yerine tercih etmenin asıl sebebi de bu: forEach içindeki callback'ten break ile çıkamazsınız, ama for...of buna izin verir.

Yan yana karşılaştırma

index.js
Output
Click Run to see the output here.

Dört farklı döngü, dört farklı görev ama aslında tek bir zihinsel model: Iterable bir şeyden değerleri almak istiyorsan for...of kullan. Bir nesnenin özellikleriyle çalışacaksan Object.keys / Object.values / Object.entries üzerinden yine for...of ile ilerle. for...in'i ise sadece bir nesnenin (kalıtımla gelenler dahil) tüm enumerable string key'lerini gerçekten istediğin o ender durumlar için sakla.

Sırada: Truthy ve Falsy

JavaScript'teki her döngü ve her if, eninde sonunda aynı soruyu sorar: bu değer true sayılıyor mu? Ve bu sorunun cevabı her zaman göründüğü kadar net değildir — boş string, sıfır, null ve undefined, hepsi beklediğinden farklı davranabilir. Sırada truthy ve falsy değerler var.

Sıkça Sorulan Sorular

JavaScript'te for...of ile for...in arasındaki fark nedir?

for...of, dizi, string, Map, Set gibi iterable yapıların değerleri üzerinde döner. for...in ise bir nesnenin anahtarları (property isimleri) üzerinde döner. Örneğin ['a', 'b'] dizisinde for...of size 'a' ve 'b' değerlerini verir; for...in ise string olarak '0' ve '1' döndürür.

for...of'u nesne üzerinde kullanabilir miyim?

Doğrudan kullanamazsınız — sade nesneler iterable değildir. Önce Object.keys(obj), Object.values(obj) veya Object.entries(obj) ile bir dizi elde edip onu for...of ile dönmeniz gerekir. En yaygın kalıp şudur: for (const [key, value] of Object.entries(obj)).

for...in dizilerde neden tercih edilmez?

Teknik olarak çalışır ama for...in tüm enumerable property'leri dolaşır; buna kalıtımla gelenler ve birinin Array.prototype'a eklediği şeyler de dahildir. Üstelik anahtarları string olarak döndürür ve integer benzeri anahtarların sırası her durumda garanti değildir. Değerler için for...of, index'e ihtiyacınız varsa klasik for döngüsünü kullanın.

Coddy ile kodlamayı öğren

BAŞLA