Klasik For Döngüsü
Bir işlemi kaç kere tekrar etmek istediğinizi biliyorsanız, gideceğiniz yer for döngüsüdür. JavaScript'te for döngüsü, sayaçlı bir döngünün üç parçasını — başlangıç, bitiş koşulu ve adım — tek bir satırda bir araya getirir.
Beş tur, beş satır çıktı. Başlığı soldan sağa okuyalım:
let i = 0döngü başlamadan önce bir kez çalışır. Sayaç burada kurulur.i < 5her turdan önce kontrol edilir.trueise gövde çalışır,falseise döngü biter.i++her turun sonunda, koşul yeniden kontrol edilmeden hemen önce çalışır.
Bu üç parça virgülle değil, noktalı virgülle ayrılır. Üçü de aslında opsiyoneldir ama boş bırakmak pek görülen bir şey değildir — o noktada zaten while kullanmak daha mantıklı olur.
Parçalar Nasıl Bir Araya Geliyor?
Sıralamayı kafada oturtmak için bir döngüyü elle adım adım takip etmek çok işe yarar:
Adım adım gidelim:
let i = 1— sayaç oluşturuldu ve 1 değeri atandı.i <= 3kontrolü — doğru, gövde çalışır.1yazdırılır.i++çalışır —iartık 2.i <= 3kontrolü — doğru.2yazdırılır.i++çalışır —iartık 3.i <= 3kontrolü — doğru.3yazdırılır.i++çalışır —iartık 4.i <= 3kontrolü — yanlış. Döngüden çıkılır.
Güncelleme adımı, gövdeden önce değil sonra çalışır. İnsanların en çok takıldığı nokta burası.
JavaScript Dizi Üzerinde Döngü Kurma
JavaScript for döngüsünün en klasik kullanım alanı bir dizinin elemanları arasında dolaşmaktır. Sayaç aynı zamanda dizinin indeksi olarak iş görür:
Dikkat edilmesi gereken birkaç nokta var:
- Diziler sıfırdan başlar (zero-indexed). İlk eleman
0indeksinde, sonuncusu iselength - 1indeksindedir. - Koşul
i <= fruits.lengthdeğil,i < fruits.lengthşeklinde.<=kullanırsan dizinin sonunu bir adım aşarsın ve ekranaundefinedbasılır. ideğişkeniletile tanımlandığı için yalnızca döngünün içinde geçerlidir. Döngü dışında böyle bir değişken yoktur.
Eğer indekse ihtiyacın yoksa, sadece değerlerle işin varsa for...of döngüsü hem daha kısa hem daha anlaşılırdır — onu ayrı bir yazıda ele alacağız.
break: Döngüden Erken Çıkmak
break ifadesi döngüyü anında sonlandırır. Aradığını bulduğunda ve devam etmeye gerek kalmadığında tam aradığın şey:
break çalıştığı anda kontrol, döngünün kapanış parantezinin hemen sonrasına atlar. Güncelleme adımı çalışmaz, koşul tekrar kontrol edilmez — döngü resmen biter.
continue: Bu turu atla
continue, o anki iterasyonun geri kalanını atlar ve doğrudan güncelleme adımına geçer. Döngü çalışmaya devam eder; sadece mevcut tur yarıda kesilir.
Çift sayılar continue ifadesine takılır ve console.log atlanır. Yalnızca tek sayılar ekrana yazılır. continue, döngünün geri kalan kısmını bir if bloğunun içine sıkıştırmadan belirli iterasyonları atlamak istediğinde oldukça işine yarar.
+1 Dışında Adımlarla İlerlemek
Güncelleme kısmı aslında sıradan bir ifade. Yani illa i++ olmak zorunda değil. Mesela ikişer ikişer sayalım:
Count down:
Bir dizi üzerinde sondan başa doğru dönmek — özellikle döngü sırasında eleman silerken oldukça işe yarar:
Ne seçerseniz seçin kural aynı: koşul ile güncelleme birbiriyle uyumlu çalışmalı ki koşul bir noktada false hale gelsin. Aksi halde döngü sonsuza kadar döner. Mesela for (let i = 0; i < 10; i--) klasik bir sonsuz döngüdür — i ters yöne gidiyor.
İç İçe For Döngüleri
Bir for döngüsünün içine başka bir for döngüsü yazabilirsiniz. Dış döngünün her adımında, iç döngü baştan sona kadar çalışır.
Toplamda dokuz satır çıktı alırsınız — dış döngüden üç tur, her birinde içteki üç tur daha. Sayaçlara aynı değişkeni tekrar tekrar kullanmak yerine anlamlı isimler verin: row/col ya da i/j gibi.
Dikkat edilmesi gereken bir nokta var: break ve continue yalnızca içinde bulundukları en içteki döngüyü etkiler. İç döngüden break ile çıkmanız dış döngüyü durdurmaz. Bunu istiyorsanız bir bayrak (flag) değişkeni belirleyip dış döngüde kontrol edin ya da iç içe işi ayrı bir fonksiyona taşıyıp oradan return edin.
Sık Yapılan Hatalar
Yeni başlayanların sıkça takıldığı birkaç nokta:
Off-by-one (bir eksik/bir fazla) hataları. i <= arr.length yazarsanız döngü bir adım fazla döner; i < arr.length - 1 yazarsanız bir adım eksik kalır. Doğru kalıp i < arr.length şeklindedir.
Sayaç artırmayı unutmak. i++ (ya da eşdeğerini) yazmayı unutursanız sayaç hiç değişmez ve karşınıza bir javascript sonsuz döngü örneği çıkar:
for (let i = 0; i < 10; ) {
console.log(i); // asla bitmez
}
Sayaç için var kullanmak. var fonksiyon kapsamlıdır; yani sayaç döngünün dışına sızar ve closure'larda sürprizlere yol açar. let ile devam edin.
Diziyi üzerinde gezinirken değiştirmek. Eleman silmek indeksleri kaydırır ve bazı elemanları atlamanıza neden olur. Eleman silmeniz gerekiyorsa sondan başa doğru ilerleyin ya da filter ile yeni bir dizi oluşturun.
Başka Bir Şey Kullanmak Daha İyi Ne Zaman Olur?
Klasik for döngüsü her zaman elinizin altında, ama JavaScript sık karşılaşılan durumlar için daha kısa alternatifler sunuyor:
- Bir dizinin değerleri üzerinde dolaşmak için:
for (const item of array)çok daha temiz. Bu, javascript for of döngüsü olarak bilinir. - Diziyi dönüştürmek için:
array.map(fn)yeni bir dizi döndürür. - Filtrelemek için:
array.filter(fn). - Toplam almak ya da indirgeme yapmak için:
array.reduce(fn, start). - Her eleman için bir şey yapmak istiyorsanız:
array.forEach(fn).
Klasik for döngüsünü ise gerçekten indekse ihtiyaç duyduğunuzda, ortadan atlamak veya break ile çıkmak istediğinizde ya da tersten saymak veya ikişer ikişer artırmak gibi alışılmadık adımlar gerektiğinde tercih edin.
Sırada: While Döngüleri
for döngüsü, aralığı baştan bildiğiniz durumlarda parlar. Ama bilmiyorsanız — yani bir koşul değişene kadar devam etmek istiyorsanız — while ve do...while daha uygun düşer. Bir sonraki sayfanın konusu tam olarak bu.
Sıkça Sorulan Sorular
JavaScript'te for döngüsünün söz dizimi nedir?
Parantez içinde noktalı virgülle ayrılmış üç parça vardır: for (başlangıç; koşul; güncelleme) { ... }. Başlangıç yalnızca bir kez çalışır, koşul her iterasyondan önce kontrol edilir, güncelleme ise her iterasyonun sonunda çalışır. Tipik bir döngü şöyle görünür: for (let i = 0; i < 10; i++) { ... }.
JavaScript'te bir dizi üzerinde nasıl dönerim?
Index'li klasik for döngüsü işini görür: for (let i = 0; i < arr.length; i++) { console.log(arr[i]); }. Index'e ihtiyacın yoksa for...of çok daha temiz bir seçenek: for (const item of arr) { ... }. Dönüştürme ya da filtreleme yapacaksan genelde doğru araç map ve filter gibi dizi metotlarıdır.
for döngüsü içinde break ve continue nasıl çalışır?
break döngüden anında çıkar; akış doğrudan döngüden sonraki koda atlar. continue ise o anki iterasyonun geri kalanını atlar, doğrudan güncelleme adımına geçer ve koşulu tekrar kontrol eder. Label (etiket) kullanmadığın sürece ikisi de yalnızca en içteki döngüyü etkiler.
for döngüm neden sonsuza kadar çalışıyor?
Büyük ihtimalle güncelleme adımı koşulu hiçbir zaman false'a yaklaştırmıyordur. for (let i = 0; i < 10; i--) sonsuza kadar döner çünkü i 0'dan başlar ve her adımda daha da negatif olur. Koşul ve güncelleme adımını birlikte kontrol et; eninde sonunda koşulun false olacak şekilde çalışmaları gerekir.