İçeriğe geç
academia.sh

Ders 11 / 21

Koşullar ve Seçim

`if` zincirleri ve koruma cümleleri, üçlü işleç, `switch` deyiminin katı eşitliği, düşme davranışı ve durum bloklarında kapsam.

İçindekiler

Değer modeli tamamlandı. Bu konu, o değerlerle program akışı kurmayı ele alıyor: hangi kodun hangi koşulda çalışacağı, tekrarın nasıl yazılacağı ve işin nasıl fonksiyonlara bölüneceği. Programlama Temelleri kursundaki Koşullu Dallanma dersinde bu yapıların amacı kurulmuştu; burada JavaScript’e özgü kurallar ele alınacak.

Koşullu seçimde dile özgü olan üç şey vardır: koşulun mantıksal değere nasıl çevrildiği (önceki ders), üçlü işlecin bir ifade olması ve switch deyiminin hangi eşitliği kullandığı.

Koşul Zinciri ve Koruma Cümleleri

if deyimi, parantez içindeki ifadeyi mantıksal değere çevirir ve doğru sayılıyorsa gövdeyi çalıştırır. Zincir else if ile sürdürülür.

Zincirin başına konan koruma cümleleri (guard clause) — geçersiz durumu erken döndüren koşullar — asıl mantığı iç içe bloklardan kurtarır:

function siniflandir(sicaklik) {
  if (sicaklik == null || Number.isNaN(sicaklik)) {
    return "gecersiz";
  }
  if (sicaklik < 18) {
    return "dusuk";
  } else if (sicaklik < 22) {
    return "normal";
  } else {
    return "yuksek";
  }
}

for (const d of [17.9, 18, 21.5, 22, 23, null, NaN]) {
  console.log(String(d).padEnd(5), siniflandir(d));
}
17.9  dusuk
18    normal
21.5  normal
22    yuksek
23    yuksek
null  gecersiz
NaN   gecersiz

Koruma cümlesi iki denetimi birleştiriyor. == null yazımı Eşitlik Karşılaştırmaları dersinde tanımlanan istisnadır: hem null hem undefined durumunu kapsar. Number.isNaN ise geçersiz sayıyı yakalar; NaN hiçbir karşılaştırmayı geçemediği için korunmasa siniflandir(NaN) sessizce "yuksek" verirdi — her üç karşılaştırma da yanlış çıkar ve akış son else dalına düşerdi.

Sınır değerlerinin hangi tarafa düştüğü çıktıdan okunuyor: 18 normale, 22 yükseğe gitti. Karşılaştırma işleçlerinin seçimi (< mi <= mi) bu sınırları belirler ve tanımın parçasıdır.

Süslü ayraçlar tek deyimlik gövdelerde zorunlu değildir, ancak kursta her zaman yazılacaktır. Gerekçe, sonradan eklenen ikinci deyimin sessizce koşulun dışında kalmasıdır.

Üçlü İşleç

if bir deyimdir: değer üretmez, akışı yönlendirir. Üçlü işleç ise bir ifadedir: değer üretir ve değer beklenen her yere yazılabilir.

const sicaklik = 21.5;
const durum = sicaklik >= 22 ? "yuksek" : sicaklik >= 18 ? "normal" : "dusuk";
console.log(durum);
console.log(`${sicaklik} derece: ${sicaklik > 20 ? "esik ustu" : "esik alti"}`);
normal
21.5 derece: esik ustu

İkinci satır, ifade olmanın somut faydasını gösteriyor: metin şablonunun içine bir koşul yerleştirildi. if deyimi oraya yazılamazdı.

Zincirlenmiş üçlü işleç sağa doğru birleşir; ikinci soru işareti, birinci ifadenin yanlış dalının içindedir. Bu yazım ikiden fazla dalda okunaklılığını hızla kaybeder. Kursun kuralı: üçlü işleç en fazla bir kez zincirlenir, daha fazlası if zinciriyle ya da bir eşleme nesnesiyle yazılır.

switch Deyimi

switch, bir değeri birden çok sabitle karşılaştırır. Eşleştirme katı eşitlikle yapılır — Eşitlik Karşılaştırmaları dersindeki üç işleçten biri, ===.

function birim(alan) {
  switch (alan) {
    case "sicaklik":
      return "C";
    case "nem":
      return "%";
    case "basinc":
      return "hPa";
    default:
      return "bilinmiyor";
  }
}
console.log(birim("sicaklik"), birim("nem"), birim("ruzgar"));
C % bilinmiyor

Katı eşitlik kullanılması, zorlama beklentisini ortadan kaldırır:

function sinama(deger) {
  switch (deger) {
    case 1:
      return "sayi bir";
    case "1":
      return "metin bir";
    default:
      return "eslesmedi";
  }
}
console.log(sinama(1), "|", sinama("1"), "|", sinama(true));
sayi bir | metin bir | eslesmedi

Sayı 1 ile metin "1" ayrı dallara gitti. true değeri hiçbirine eşleşmedi — gevşek eşitlikte true == 1 doğru olurdu, ama switch gevşek eşitlik kullanmaz.

Düşme

switch deyimi eşleşen case etiketinden başlar ve bir break ya da return ile karşılaşana kadar aşağı doğru akar. Bu davranışa düşme (fall-through) denir ve kasıtsız yapıldığında sessiz hata üretir:

function etiket(alan) {
  let sonuc = "";
  switch (alan) {
    case "sicaklik":
      sonuc = "sicaklik (C)";
    case "nem":
      sonuc += " nem (%)";
      break;
    default:
      sonuc = "bilinmiyor";
  }
  return sonuc;
}
console.log(JSON.stringify(etiket("sicaklik")));
console.log(JSON.stringify(etiket("nem")));
console.log(JSON.stringify(etiket("basinc")));
"sicaklik (C) nem (%)"
" nem (%)"
"bilinmiyor"

İlk satırda akış birinci daldan ikinciye düştü ve iki metin birleşti. Yazarın niyeti bu değildi. Çıktılar JSON.stringify ile yazıldı; aksi halde ikinci satırdaki baştaki boşluk görünmezdi.

Düşme bilinçli kullanıldığında birden çok değeri aynı dala bağlar:

function grup(istasyon) {
  switch (istasyon) {
    case "A1":
    case "A2":
      return "A grubu";
    case "B1":
      return "B grubu";
    default:
      return "bilinmiyor";
  }
}
console.log(grup("A1"), "|", grup("A2"), "|", grup("B1"), "|", grup("C9"));
A grubu | A grubu | B grubu | bilinmiyor

Boş case etiketleri gövdesizdir; akış doğrudan bir sonrakine düşer. Bu, dilin kabul edilen kullanımıdır ve okunması güç değildir — gövdeli bir daldan diğerine düşmek ise kursta yazılmayacaktır.

Durum Bloklarında Kapsam

switch gövdesinin tamamı tek bir bloktur. Ayrı case etiketleri ayrı kapsam açmaz; bu yüzden iki dalda aynı adı bildirmek ayrıştırma hatası verir:

switch (1) {
  case 1:
    const x = 1;
    break;
  case 2:
    const x = 2;
    break;
}
SyntaxError: Identifier 'x' has already been declared

Değişken Bildirimleri dersindeki yeniden bildirim kuralı burada beklenmedik bir yerde karşımıza çıkıyor. Çözüm, her dalı süslü ayraçlarla kendi bloğuna almaktır:

switch (1) {
  case 1: {
    const x = "birinci";
    console.log(x);
    break;
  }
  case 2: {
    const x = "ikinci";
    console.log(x);
    break;
  }
}
birinci

Seçim Yapısının Seçimi

Üç yapı arasındaki seçim, karşılaştırmanın biçimine göre yapılır.

switch, tek bir değeri sabitlerle karşılaştırdığında uygundur. Aralık denetimi, birleşik koşul veya sıfırdan farklı bir karşılaştırma gerekiyorsa if zinciri gerekir.

Sabit eşlemeler, üçüncü bir seçenek sunar: bir nesneye anahtar–değer olarak yazılıp doğrudan okunabilirler.

const BIRIMLER = { sicaklik: "C", nem: "%", basinc: "hPa" };

function birim(alan) {
  return BIRIMLER[alan] ?? "bilinmiyor";
}
console.log(birim("sicaklik"), birim("ruzgar"));
C bilinmiyor

Bu yazım, eşleme büyüdükçe okunaklılığını korur ve veri ile kodu ayırır. ?? işlecinin kullanılması bilinçlidir: eşlemede karşılığı 0 veya boş dizgi olan bir anahtar bulunsaydı, || yazımı onu da varsayılana düşürürdü.

Özet

  • Koruma cümleleri geçersiz durumu erken döndürür ve asıl mantığı iç içe bloklardan kurtarır; NaN denetimi korunmazsa akış sessizce son dala düşer.
  • Üçlü işleç bir ifadedir ve değer beklenen her yere yazılabilir; en fazla bir kez zincirlenir.
  • switch katı eşitlikle eşleştirir; zorlama yapmaz.
  • Akış eşleşen etiketten başlar ve break ya da return görene kadar düşer; gövdesiz etiketler birden çok değeri aynı dala bağlar.
  • switch gövdesi tek bir bloktur; dallarda ad bildirmek için her dal kendi süslü ayraçlarına alınır.
  • Sabit eşlemeler nesne olarak yazıldığında switch yerine geçer ve ?? ile varsayılan alır.

Sonraki Adım

Koşullar tek bir kaydı sınıflandırdı. Ölçüm listesinin tamamını işlemek için tekrar gerekiyor. Sonraki ders döngü biçimlerini ele alacak: sayaçlı döngü, koşullu döngü ve iki farklı koleksiyon döngüsü. İki koleksiyon döngüsü arasındaki fark — birinin anahtarları, diğerinin değerleri vermesi — dizilerde beklenmedik sonuçlar üretir.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat