Site icon Akbuz

GOTO Ölmedi, JavaScript’te Yaşıyor: Labeled Statements Nedir?

Labeled Statements

JavaScript dünyasında popüler framework’lerden, yeni gelen async/await özelliklerinden ya da bildiğimiz console.log taktiklerinden bahsetmeyeceğim. Bugün, muhtemelen production kodunda çok nadiren karşılaştığın ama karşılaştığında “Hadi canım, bu nasıl çalışıyor?” diyeceğin, JS’in en karanlık ve en büyüleyici köşelerinden birine bakacağız: Labeled Statements (Etiketli İfadeler) ve İç İçe Döngülerin Kontrolü.

Çoğu JavaScript geliştiricisi etiketleri (labels) duyduğunda akıllarına doğrudan antik programlama dillerindeki o meşhur ve tehlikeli goto komutu gelir. Sakin ol, JS’te goto yok. Ama iç içe geçmiş devasa döngülerden (nested loops) tek bir hamlede, tereyağından kıl çeker gibi kurtulmanı sağlayacak harika bir mekanizma var.

Gelin, bu niş özelliği ve karmaşık algoritmaları nasıl daha okunabilir kıldığını birlikte inceleyelim.

Labeled Statements Nedir?

JavaScript’te herhangi bir döngünün (for, while) veya kod bloğunun önüne bir isim (etiket) koyup sonuna iki nokta üst üste (:) ekleyebilirsin. Bu etiket, JavaScript motoruna “Bak, bu bloğun adı artık bu, ona göre!” demektir.

Peki bu ne işe yarar? İç içe döngülerle çalışırken break veya continue dediğinde, JS varsayılan olarak sadece en içteki döngüyü etkiler. Ama dıştaki döngüyü kırmak istiyorsan, normalde araya bayraklar (flag = true gibi boolean değişkenler) koyman gerekir. İşte etiketler seni bu ekstra değişken hamallığından kurtarır.

Kod Üzerinde Görelim: Matris Araması

Diyelim ki elimizde iki boyutlu bir oyun haritası (matris) var ve içinde belirli bir hedefi arıyoruz. Hedefi bulduğumuz anda tüm arama işlemini (hem iç hem dış döngüyü) durdurmak istiyoruz.

Eski ve Yorucu Yöntem (Flag Kullanarak)

JavaScript

const matrix = [
  [1, 2, 3],
  [4, 5, 6], // Diyelim ki 5'i arıyoruz
  [7, 8, 9]
];

const target = 5;
let found = false; // İşte o sinir bozucu flag değişkeni

for (let i = 0; i < matrix.length; i++) {
  for (let j = 0; j < matrix[i].length; j++) {
    if (matrix[i][j] === target) {
      console.log(`Hedef bulundu: [${i}, ${j}]`);
      found = true; 
      break; // Sadece içteki döngüyü kırar
    }
  }
  if (found) {
    break; // Dıştaki döngüyü de kırmak için mecbur buraya da yazdık
  }
}

Kötü mü? Değil. Ama temiz de değil. Kodu okuyan kişi found değişkenini sürekli takip etmek zorunda.

Havalı ve Temiz Yöntem (Etiket Kullanarak)

Şimdi aynı senaryoyu JavaScript’in bu niş özelliğini kullanarak yazalım. Dış döngümüze bir isim veriyoruz: disDongu.

JavaScript

const matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
];

const target = 5;

// Döngüye etiket tanımlıyoruz
disDongu: for (let i = 0; i < matrix.length; i++) {
  for (let j = 0; j < matrix[i].length; j++) {
    if (matrix[i][j] === target) {
      console.log(`Hedef bulundu: [${i}, ${j}]`);
      
      // Tek hamlede en dıştaki döngüyü patlatıyoruz!
      break disDongu; 
    }
  }
}

console.log("Arama bitti, kod buraya zıpladı.");

Nasıl? Aradaki found değişkeni tamamen yok oldu. break disDongu; satırı çalıştığı anda, JavaScript doğrudan disDongu: etiketinin bittiği yere (yani 16. satıra) ışınlanıyor.

Sadece break mi? Hayır, continue da Var!

Aynı mantık continue için de geçerli. Diyelim ki içteki döngüde bir hata yakaladın ya da aramaman gereken bir alan gördün, içteki döngüyü pas geçip dıştaki döngünün bir sonraki adımına (i++) atlamak istiyorsun:

JavaScript

satirKontrol: for (let i = 0; i < matrix.length; i++) {
  for (let j = 0; j < matrix[i].length; j++) {
    if (matrix[i][j] === "yasakli_bolge") {
      // Bu satırın kalanını tarama, doğrudan bir sonraki satıra (i+1) geç!
      continue satirKontrol; 
    }
    // İşlemler...
  }
}

Peki Neden Her Yerde Görmüyoruz? (Büyük Sorumluluk)

Bu kadar pratik bir şey neden popüler değil? Cevap basit: Okunabilirlik ve alışkanlıklar.

Yazılım dünyasında kodun yukarıdan aşağıya lineer akması istenir. Etiketler (özellikle çok fazla iç içe döngü ve etiket olan karmaşık kodlarda) bir süre sonra spagetti koda dönebilir. Başka bir geliştirici koduna baktığında “Bu etiket de nereden çıktı, kod nereye zıplıyor?” diye afallayabilir.

Ayrıca modern JavaScript’te matris işlemleri için genellikle flatMap, some veya find gibi fonksiyonel metotlar tercih ediliyor. Ama performansın kritik olduğu, oyun motoru yazdığın (örneğin Unity mantığında JS/TS tabanlı bir yapı) veya devasa veri setlerini ham for döngüsüyle dönmen gereken durumlarda bu teknik tam bir hayat kurtarıcıdır.

Özet

JavaScript’te her gün yeni bir kütüphane öğreniyoruz ama dilin kendi içindeki bu tarz mikro yetenekleri bilmek vizyon katıyor. Bir dahaki sefere iç içe döngüler arasında kaybolup boolean bayraklarıyla boğuştuğunda, yukarıya ufak bir etiket iliştirmeyi unutma.

Kodlarında bu tarz gizli cevherleri kullanıyor musun, yoksa “Aman abi, kodun okunabilirliği bozulur” diyenlerden misin?

Exit mobile version