JavaScript Eğitimi #4: Döngüler - Tekrarlayan İşlemleri Otomatikleştirme
JavaScript'te for, while ve do-while döngülerini öğrenin. break, continue ve iç içe döngülerle tekrarlayan işlemleri verimli şekilde yönetin.
JavaScript Eğitimi #4: Döngüler
Önceki derslerde koşullu ifadelerle programlarımıza karar verme yeteneği kazandırdık. Şimdi sıra tekrarlayan işlemlerde. Bir listedeki tüm ürünleri göstermek, 1'den 100'e kadar saymak, kullanıcıdan doğru şifre alana kadar sormak - bu işlemler döngülerle yapılır.
Düşünün ki bir sınıftaki 30 öğrencinin notunu ekrana yazdırmanız gerekiyor. Her öğrenci için ayrı ayrı console.log() yazmak mı? Tabii ki hayır. Döngüler bu tekrarlayan işlemleri birkaç satır kodla çözmenizi sağlar.
İçindekiler
- Döngü Nedir?
- for Döngüsü
- while Döngüsü
- do-while Döngüsü
- break ve continue
- for...of Döngüsü
- for...in Döngüsü
- İç İçe Döngüler
- Pratik Örnekler
- Performans ve İpuçları
- Sık Sorulan Sorular
- Sonuç
Döngü Nedir?
Döngü, belirli bir kod bloğunu tekrar tekrar çalıştırmanızı sağlayan yapıdır. Her programlama dilinde döngüler vardır ve en temel kavramlardan biridir.
Döngüsüz dünya nasıl olurdu?
// 1'den 5'e kadar yazdırmak için döngüsüz:
console.log(1);
console.log(2);
console.log(3);
console.log(4);
console.log(5);
// Ya 1000'e kadar yazdırmak isteseydiniz? 1000 satır kod mu?İşte döngülerle aynı iş:
for (let i = 1; i <= 5; i++) {
console.log(i);
}
// Çıktı: 1, 2, 3, 4, 5
// 1000'e kadar mı? Sadece 5'i 1000 yap:
for (let i = 1; i <= 1000; i++) {
console.log(i);
}for Döngüsü
En yaygın kullanılan döngü tipi. Kaç kez tekrarlanacağı önceden belli olan durumlarda kullanılır.
Sözdizimi
for (başlangıç; koşul; artış) {
// Tekrarlanacak kod
}- başlangıç: Döngü başlamadan önce bir kez çalışır (genellikle sayaç tanımlama)
- koşul: Her döngüde kontrol edilir,
trueise devam eder - artış: Her döngü sonunda çalışır (genellikle sayaç artırma)
for (let i = 0; i < 5; i++) {
console.log("Tekrar: " + i);
}
// Çıktı:
// Tekrar: 0
// Tekrar: 1
// Tekrar: 2
// Tekrar: 3
// Tekrar: 4Adım Adım İnceleme
for (let i = 1; i <= 3; i++) {
console.log(i);
}
// 1. Adım: let i = 1 (sayaç oluştur)
// 2. Adım: i <= 3 kontrol (1 <= 3? true, devam et)
// 3. Adım: console.log(1) çalış
// 4. Adım: i++ (i = 2 oldu)
// 5. Adım: i <= 3 kontrol (2 <= 3? true, devam et)
// 6. Adım: console.log(2) çalış
// 7. Adım: i++ (i = 3 oldu)
// 8. Adım: i <= 3 kontrol (3 <= 3? true, devam et)
// 9. Adım: console.log(3) çalış
// 10. Adım: i++ (i = 4 oldu)
// 11. Adım: i <= 3 kontrol (4 <= 3? false, döngü biter)Farklı Kullanımlar
// Geriye sayma
for (let i = 10; i >= 1; i--) {
console.log(i);
}
// 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
// 2'şer artış
for (let i = 0; i <= 10; i += 2) {
console.log(i);
}
// 0, 2, 4, 6, 8, 10
// 5'er azalış
for (let i = 100; i >= 0; i -= 5) {
console.log(i);
}
// 100, 95, 90, 85, ... 5, 0
// Çift katı artış
for (let i = 1; i <= 1000; i *= 2) {
console.log(i);
}
// 1, 2, 4, 8, 16, 32, 64, 128, 256, 512Dizi ile Kullanım
const meyveler = ["elma", "armut", "muz", "kiraz"];
// Index ile erişim
for (let i = 0; i < meyveler.length; i++) {
console.log(i + ": " + meyveler[i]);
}
// 0: elma
// 1: armut
// 2: muz
// 3: kiraz
// Tersten yazdırma
for (let i = meyveler.length - 1; i >= 0; i--) {
console.log(meyveler[i]);
}
// kiraz, muz, armut, elmawhile Döngüsü
Koşul true olduğu sürece devam eder. Kaç kez döneceği önceden belli olmayan durumlarda kullanılır.
Sözdizimi
while (koşul) {
// Koşul true olduğu sürece tekrarlanır
}let sayac = 1;
while (sayac <= 5) {
console.log(sayac);
sayac++;
}
// 1, 2, 3, 4, 5Dikkat: Sonsuz Döngü
Koşul hiç false olmazsa döngü sonsuza dek devam eder (ve programınız çöker):
// DİKKAT: Sonsuz döngü!
// let i = 0;
// while (i < 5) {
// console.log(i);
// // i++ unutuldu! i hep 0 kalacak
// }
// Doğru kullanım:
let i = 0;
while (i < 5) {
console.log(i);
i++; // Önemli!
}Pratik Örnek: Kullanıcı Girişi
// Doğru şifre girilene kadar sor
let dogrusifre = "12345";
let girilenSifre = "";
let deneme = 0;
const maxDeneme = 3;
while (girilenSifre !== dogrusifre && deneme < maxDeneme) {
// Gerçek uygulamada prompt() veya form kullanılır
girilenSifre = prompt("Şifrenizi girin:");
deneme++;
if (girilenSifre === dogrusifre) {
console.log("Giriş başarılı!");
} else if (deneme < maxDeneme) {
console.log(`Yanlış şifre. ${maxDeneme - deneme} hakkınız kaldı.`);
} else {
console.log("Çok fazla hatalı deneme. Hesabınız kilitlendi.");
}
}while vs for
// Aynı işi yapan for ve while
// for kullanımı - kaç kez döneceği belli
for (let i = 0; i < 5; i++) {
console.log(i);
}
// while kullanımı
let i = 0;
while (i < 5) {
console.log(i);
i++;
}
// Genel kural:
// - Kaç kez döneceği belliyse: for
// - Bir koşula bağlıysa: whiledo-while Döngüsü
while döngüsüne benzer ama koşul sonda kontrol edilir. Bu, döngünün en az bir kez çalışacağı anlamına gelir.
Sözdizimi
do {
// En az bir kez çalışır
} while (koşul);let sayi = 10;
// while - koşul başta, hiç çalışmaz
while (sayi < 5) {
console.log("while: " + sayi);
sayi++;
}
// do-while - koşul sonda, en az bir kez çalışır
sayi = 10;
do {
console.log("do-while: " + sayi);
sayi++;
} while (sayi < 5);
// Çıktı: do-while: 10Kullanım Senaryosu: Menü
let secim;
do {
console.log("\n=== MENÜ ===");
console.log("1. Yeni Oyun");
console.log("2. Ayarlar");
console.log("3. Çıkış");
secim = prompt("Seçiminiz (1-3):");
switch (secim) {
case "1":
console.log("Yeni oyun başlatılıyor...");
break;
case "2":
console.log("Ayarlar açılıyor...");
break;
case "3":
console.log("Güle güle!");
break;
default:
console.log("Geçersiz seçim!");
}
} while (secim !== "3");break ve continue
Döngülerin akışını kontrol etmek için kullanılır.
break
Döngüyü tamamen sonlandırır:
// 5'i bulunca dur
for (let i = 1; i <= 10; i++) {
if (i === 5) {
console.log("5 bulundu, döngüden çıkılıyor");
break;
}
console.log(i);
}
// Çıktı: 1, 2, 3, 4, "5 bulundu, döngüden çıkılıyor"
// Arama örneği
const isimler = ["Ali", "Veli", "Ayşe", "Fatma"];
let aranan = "Ayşe";
let bulundu = false;
for (let i = 0; i < isimler.length; i++) {
if (isimler[i] === aranan) {
console.log(`${aranan} index ${i}'de bulundu!`);
bulundu = true;
break; // Bulduk, aramaya devam etmeye gerek yok
}
}
if (!bulundu) {
console.log(`${aranan} listede yok.`);
}continue
Mevcut döngüyü atlar, sonrakine geçer:
// Sadece çift sayıları yazdır
for (let i = 1; i <= 10; i++) {
if (i % 2 !== 0) {
continue; // Tek sayıyı atla
}
console.log(i);
}
// Çıktı: 2, 4, 6, 8, 10
// Negatif sayıları atla
const sayilar = [1, -2, 3, -4, 5, -6];
let toplam = 0;
for (let i = 0; i < sayilar.length; i++) {
if (sayilar[i] < 0) {
continue; // Negatifi atla
}
toplam += sayilar[i];
}
console.log("Pozitif sayıların toplamı:", toplam); // 9break vs continue Karşılaştırma
console.log("--- break örneği ---");
for (let i = 1; i <= 5; i++) {
if (i === 3) break;
console.log(i);
}
// Çıktı: 1, 2
console.log("--- continue örneği ---");
for (let i = 1; i <= 5; i++) {
if (i === 3) continue;
console.log(i);
}
// Çıktı: 1, 2, 4, 5Etiketli Döngüler (Labeled Loops)
İç içe döngülerde dış döngüyü kontrol etmek için:
dis: for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (i === 1 && j === 1) {
break dis; // Dış döngüyü kır
}
console.log(i, j);
}
}
// Çıktı: 0,0 | 0,1 | 0,2 | 1,0
// (1,1'de dış döngü kırıldı)for...of Döngüsü
Dizi veya iterable (gezilebilir) yapıların elemanları üzerinde dolaşır. ES6 ile geldi.
const meyveler = ["elma", "armut", "muz"];
// for...of ile
for (const meyve of meyveler) {
console.log(meyve);
}
// elma, armut, muz
// Klasik for ile aynı işi yapmak
for (let i = 0; i < meyveler.length; i++) {
console.log(meyveler[i]);
}Avantajları
// String üzerinde
const metin = "Merhaba";
for (const harf of metin) {
console.log(harf);
}
// M, e, r, h, a, b, a
// Index'e ihtiyacınız yoksa daha temiz
const sayilar = [10, 20, 30, 40];
let toplam = 0;
for (const sayi of sayilar) {
toplam += sayi;
}
console.log(toplam); // 100
// Index gerekiyorsa entries() kullanın
for (const [index, sayi] of sayilar.entries()) {
console.log(`Index ${index}: ${sayi}`);
}for...in Döngüsü
Nesne (object) özellikleri üzerinde dolaşır. Diziler için for...of tercih edilir.
const kisi = {
isim: "Ahmet",
yas: 25,
sehir: "İstanbul"
};
for (const anahtar in kisi) {
console.log(`${anahtar}: ${kisi[anahtar]}`);
}
// isim: Ahmet
// yas: 25
// sehir: İstanbulfor...in vs for...of
const dizi = ["a", "b", "c"];
// for...in - index döner (diziler için önerilmez)
for (const i in dizi) {
console.log(i); // "0", "1", "2" (string!)
}
// for...of - değer döner (diziler için ideal)
for (const eleman of dizi) {
console.log(eleman); // "a", "b", "c"
}
// Genel kural:
// - Diziler için: for...of
// - Nesneler için: for...inİç İçe Döngüler
Bir döngü içinde başka bir döngü. Çok boyutlu veriler veya kombinasyonlar için kullanılır.
Basit Örnek
// Çarpım tablosu
for (let i = 1; i <= 5; i++) {
let satir = "";
for (let j = 1; j <= 5; j++) {
satir += (i * j).toString().padStart(4, " ");
}
console.log(satir);
}
// Çıktı:
// 1 2 3 4 5
// 2 4 6 8 10
// 3 6 9 12 15
// 4 8 12 16 20
// 5 10 15 20 25Yıldız Piramidi
// Sağa yaslanmış üçgen
const satirSayisi = 5;
for (let i = 1; i <= satirSayisi; i++) {
let yildizlar = "";
for (let j = 1; j <= i; j++) {
yildizlar += "* ";
}
console.log(yildizlar);
}
// *
// * *
// * * *
// * * * *
// * * * * *
// Ortalanmış piramit
for (let i = 1; i <= satirSayisi; i++) {
let satir = " ".repeat(satirSayisi - i) + "* ".repeat(i);
console.log(satir);
}
// *
// * *
// * * *
// * * * *
// * * * * *2 Boyutlu Dizi
const matris = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
// Tüm elemanları yazdır
for (let i = 0; i < matris.length; i++) {
for (let j = 0; j < matris[i].length; j++) {
console.log(`matris[${i}][${j}] = ${matris[i][j]}`);
}
}
// Toplam hesapla
let toplam = 0;
for (const satir of matris) {
for (const eleman of satir) {
toplam += eleman;
}
}
console.log("Toplam:", toplam); // 45Pratik Örnekler
Örnek 1: FizzBuzz
Klasik programlama sorusu:
// 1'den 100'e kadar say
// 3'e bölünenler için "Fizz" yaz
// 5'e bölünenler için "Buzz" yaz
// Her ikisine de bölünenler için "FizzBuzz" yaz
for (let i = 1; i <= 100; i++) {
let cikti = "";
if (i % 3 === 0) cikti += "Fizz";
if (i % 5 === 0) cikti += "Buzz";
console.log(cikti || i);
}
// 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz...Örnek 2: Asal Sayı Kontrolü
function asalMi(sayi) {
if (sayi < 2) return false;
if (sayi === 2) return true;
if (sayi % 2 === 0) return false;
for (let i = 3; i <= Math.sqrt(sayi); i += 2) {
if (sayi % i === 0) {
return false;
}
}
return true;
}
// 1-50 arası asal sayıları bul
console.log("1-50 arası asal sayılar:");
for (let i = 1; i <= 50; i++) {
if (asalMi(i)) {
console.log(i);
}
}
// 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47Örnek 3: Fibonacci Dizisi
function fibonacciDizisi(n) {
const dizi = [0, 1];
for (let i = 2; i < n; i++) {
dizi[i] = dizi[i - 1] + dizi[i - 2];
}
return dizi;
}
console.log(fibonacciDizisi(10));
// [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]Örnek 4: Dizi Arama ve Filtreleme
const ogrenciler = [
{ isim: "Ali", puan: 85 },
{ isim: "Veli", puan: 72 },
{ isim: "Ayşe", puan: 90 },
{ isim: "Fatma", puan: 65 },
{ isim: "Mehmet", puan: 78 }
];
// 80 ve üzeri alanları bul
console.log("Başarılı öğrenciler:");
for (const ogrenci of ogrenciler) {
if (ogrenci.puan >= 80) {
console.log(`${ogrenci.isim}: ${ogrenci.puan}`);
}
}
// En yüksek puanı bul
let enYuksek = ogrenciler[0];
for (const ogrenci of ogrenciler) {
if (ogrenci.puan > enYuksek.puan) {
enYuksek = ogrenci;
}
}
console.log(`En başarılı: ${enYuksek.isim} (${enYuksek.puan})`);
// Ortalama hesapla
let toplam = 0;
for (const ogrenci of ogrenciler) {
toplam += ogrenci.puan;
}
const ortalama = toplam / ogrenciler.length;
console.log(`Sınıf ortalaması: ${ortalama.toFixed(2)}`);Örnek 5: Sayı Tahmin Oyunu
function sayiTahminOyunu() {
const hedef = Math.floor(Math.random() * 100) + 1;
let tahmin;
let denemeSayisi = 0;
const maxDeneme = 7;
console.log("1-100 arası bir sayı tuttum. Tahmin et!");
console.log(`${maxDeneme} hakkın var.`);
while (denemeSayisi < maxDeneme) {
tahmin = parseInt(prompt("Tahminin:"));
denemeSayisi++;
if (isNaN(tahmin)) {
console.log("Geçerli bir sayı gir!");
denemeSayisi--; // Geçersiz giriş hakkı yemesin
continue;
}
if (tahmin === hedef) {
console.log(`Tebrikler! ${denemeSayisi} denemede bildin!`);
return;
} else if (tahmin < hedef) {
console.log("Daha büyük!");
} else {
console.log("Daha küçük!");
}
console.log(`Kalan hak: ${maxDeneme - denemeSayisi}`);
}
console.log(`Kaybettin! Sayı ${hedef} idi.`);
}
// Tarayıcı konsolunda çalıştırın
// sayiTahminOyunu();Performans ve İpuçları
Döngü Optimizasyonu
const buyukDizi = new Array(10000).fill(0);
// Yavaş: Her döngüde length hesaplanır
for (let i = 0; i < buyukDizi.length; i++) {
// ...
}
// Hızlı: length bir kez hesaplanır
const uzunluk = buyukDizi.length;
for (let i = 0; i < uzunluk; i++) {
// ...
}
// Veya daha kısa
for (let i = 0, len = buyukDizi.length; i < len; i++) {
// ...
}Gereksiz Döngü Kaçınma
// Kötü: Bulduktan sonra da devam eder
let sonuc = null;
for (const item of dizi) {
if (item.id === arananId) {
sonuc = item;
}
}
// İyi: Bulunca çıkar
let sonuc = null;
for (const item of dizi) {
if (item.id === arananId) {
sonuc = item;
break; // Bulduk, çık
}
}
// Daha iyi: find() metodu
const sonuc = dizi.find(item => item.id === arananId);Döngü Seçimi
// Index gerekiyorsa: klasik for
for (let i = 0; i < dizi.length; i++) {
console.log(i, dizi[i]);
}
// Sadece değer gerekiyorsa: for...of
for (const item of dizi) {
console.log(item);
}
// Nesne özellikleri: for...in
for (const key in nesne) {
console.log(key, nesne[key]);
}
// Array metodları: forEach, map, filter, reduce
dizi.forEach((item, index) => {
console.log(index, item);
});Sık Sorulan Sorular
for ve while arasındaki fark nedir?
for döngü sayısı önceden belli olduğunda (1'den 10'a say), while bir koşula bağlı olduğunda (doğru şifre girilene kadar) kullanılır. Teknik olarak birbirinin yerine kullanılabilir ama okunabilirlik açısından uygun olanı tercih edin.
Sonsuz döngüden nasıl kaçınırım?
Döngü koşulunun bir noktada false olacağından emin olun. while döngüsünde sayacı artırmayı, for döngüsünde koşulu doğru yazmayı unutmayın. Tarayıcıda sonsuz döngüye girerseniz sekmeyi kapatmak gerekebilir.
forEach mi for...of mı?
for...of daha esnektir: break ve continue kullanabilirsiniz, async/await ile çalışır. forEach daha fonksiyonel bir yaklaşımdır. İkisi de iyi seçeneklerdir.
İç içe döngüler performans sorununa yol açar mı?
Çok büyük veri setlerinde (O(n²) karmaşıklık) yavaşlık olabilir. Mümkünse algoritmanızı optimize edin veya iç döngüden erken çıkın (break).
Döngüde değişken tanımlarken let mi var mı?
Her zaman let kullanın. var döngü dışında da erişilebilir olur ve kapanış (closure) sorunlarına yol açabilir.
Sonuç
Bu derste JavaScript'in tüm döngü yapılarını öğrendik. for döngüsüyle belirli sayıda tekrar, while ile koşula bağlı tekrar, do-while ile en az bir kez çalışan döngü yazdık. break ve continue ile döngü akışını kontrol ettik. for...of ile diziler, for...in ile nesneler üzerinde dolaştık.
Döngüler programlamanın en temel yapı taşlarından biridir. Liste işleme, arama, filtreleme, hesaplama - hepsinde döngüler kullanılır. İlerleyen derslerde diziler ve fonksiyonlarla birlikte döngülerin gücünü daha iyi göreceksiniz.
Pratik için:
- 1-100 arası 3 ve 5'e tam bölünebilen sayıları bulun
- Bir string'i ters çeviren döngü yazın
- Kullanıcıdan sayı alıp faktöriyelini hesaplayan program yazın
- İç içe döngüyle dikdörtgen çizen program yazın
Sonraki Ders
Bir sonraki derste Fonksiyonlar konusunu işleyeceğiz. Kodlarımızı nasıl organize edeceğimizi, tekrar kullanılabilir yapılar nasıl oluşturacağımızı öğreneceğiz. Function declaration, arrow function, parametre ve return kavramlarını göreceğiz.
JavaScript Eğitimi #5: Fonksiyonlar →
Kaynaklar
Projenizi Hayata Geçirelim
Web sitesi, mobil uygulama veya yapay zeka çözümü mü arıyorsunuz? Fikirlerinizi birlikte değerlendirelim.
Ücretsiz Danışmanlık Alın