Blok 1 · Ders 3
Çoklu karar ve fonksiyon
else if zinciriyle birden çok seçeneği sıralıyor, mantık işaretlerini öğreniyor ve tekrar eden kodu fonksiyona çeviriyorsun.
Bu dersin sonunda
else ifzinciriyle ikiden çok seçenek arasında seçim yaptırabilir, koşulları doğru sıraya dizebilirsin&&,||ve!ile birden çok koşulu tek bir kararda birleştirebilirsin- Bir fonksiyon tanımlayıp onu istediğin yerde, istediğin kadar çağırabilirsin
- Parametre ve argümanla fonksiyona her çağrıda farklı bilgi verebilirsin
- Tekrar eden kodu fonksiyona çevirebilir, fonksiyonun içindeki değişkenin dışarıdan neden görünmediğini açıklayabilirsin
- Fonksiyonlardaki sık hataları mesajından tanıyıp düzeltebilirsin
Bu sayfada
Ders 2'de programına iki yol arasında seçim yaptırdın: koşul doğruysa bir şey, değilse başka bir şey. Oyunda ise seçenekler çoğu zaman ikiden fazladır ve bir karar birden çok şarta bağlı olabilir. Bu derste önce else if ile istediğin kadar seçenek eklemeyi, sonra &&, || ve ! işaretleriyle koşulları birleştirmeyi öğreneceksin.
Dersin ikinci yarısı programlamanın en önemli fikirlerinden birine ayrıldı: fonksiyon. Bir işi bir kez yazıp ona ad vereceksin, sonra o adı söyleyerek işi istediğin kadar yaptıracaksın. Bundan sonraki her derste fonksiyon yazacaksın.
Çok seçenek: else if
Bir oyunda oyuncunun derecesini (rank) puanına göre yazdırmak istiyorsun:
| Puan | Derece |
|---|---|
| 2000 ve üstü | Platin |
| 1500 ile 1999 arası | Altın |
| 1000 ile 1499 arası | Gümüş |
| 1000'in altı | Bronz |
if ve else yalnızca iki yol verir, burada dört yol var. İlk akla gelen, her derece için ayrı bir if yazmak. Dene:
const puan = 2200if (puan >= 2000) { console.log("Platin")}if (puan >= 1500) { console.log("Altın")}if (puan >= 1000) { console.log("Gümüş")}PlatinAltınGümüşOyuncu aynı anda üç ligde. Sebep şu: üç if birbirinden habersizdir. Her biri kendi sorusunu sorar ve 2200 üç soruya da "evet" der. Bize gereken, ilk "evet"ten sonra durmak. Bunun yolu else if:
const puan = 1200if (puan >= 2000) { console.log("Platin")} else if (puan >= 1500) { console.log("Altın")} else if (puan >= 1000) { console.log("Gümüş")} else { console.log("Bronz")}GümüşJavaScript koşulları yukarıdan aşağı, sırayla sorar. İlk true olan koşulun bloğunu çalıştırır ve zincirin geri kalanını atlar. Hiçbir koşul true değilse en sondaki else bloğu çalışır.
puan = 1200 için zincirin akış şeması. İlk iki elmasın cevabı false, üçüncüsünün true: Gümüş yazılır ve zincir biter. Platin, Altın ve else kutularına hiç sıra gelmez.Sorunun düzeldiğini kendin gör: ilk satırı const puan = 2200 yapıp yeniden çalıştır. Bu sefer ekrana yalnızca Platin gelir; 2200 ilk soruya "evet" dediği için alttaki sorular hiç sorulmaz.
Zincirin kuralları:
- Zincir her zaman
ifile başlar. Arasına istediğin kadarelse ifekleyebilirsin. else ifiki ayrı sözcüktür, aralarında boşluk vardır.- Her
else ifkendi koşul parantezini taşır.elsekoşul almaz. elseen sona yazılır ve zorunlu değildir. Yazmazsan ve hiçbir koşul tutmazsa hiçbir blok çalışmaz: yukarıdaki zincirdenelsebloğunu silip ilk satırıconst puan = 400yaparsan program hiçbir şey yazmaz.- Bir zincirde en fazla bir blok çalışır.
else: beklenmedik değerler için
Ders 2'deki "Mavi mi, kırmızı mı?" görevini hatırla: taraf değişkenine "yeşil" koyunca program else bloğuna düşüp "Üssün sağ üstte" diyordu. else if ile her geçerli değeri ayrı ayrı sorarsan else bloğunu yalnızca beklenmedik değerlere ayırabilirsin:
const taraf = "yeşil"if (taraf === "mavi") { console.log("Üssün sol altta")} else if (taraf === "kırmızı") { console.log("Üssün sağ üstte")} else { console.log("Böyle bir taraf yok: " + taraf)}Böyle bir taraf yok: yeşilYanlış bir değer artık sessizce yanlış bir yola gitmiyor; program sorunu açıkça söylüyor.
Sıra önemli: en seçici koşul en üste
Aynı zinciri ters sırayla yazıp 2200 puanla deneyelim:
const puan = 2200if (puan >= 1000) { console.log("Gümüş")} else if (puan >= 1500) { console.log("Altın")} else if (puan >= 2000) { console.log("Platin")} else { console.log("Bronz")}Gümüş2200 puanlı oyuncu Gümüş çıktı. Hata mesajı yok; program çalışıyor ama yanlış çalışıyor.
İlk soru olan puan >= 1000 çok geniş: 1500 de, 2000 de, 2200 de bu sorudan geçer. İlk soru true olunca zincir orada biter ve alttaki iki soruya hiç sıra gelmez. Bu sırayla yazılmış bir zincirde "Altın" ve "Platin" satırları hiçbir puanla çalışamaz.
Kural: >= ile sınır koyuyorsan en büyük sınırdan başla, <= ile koyuyorsan en küçükten. Kısacası dar (seçici) koşul üste, geniş koşul alta.
elseif diye bitişik yazmak ve else bloğundan sonra bir else if daha eklemek, bu konunun en sık iki hatası. Mesajlarını aşağıda Sık hatalar bölümünde göreceksin.
Mantık işaretleri: &&, || ve !
Bazı kararlar tek bir koşula bağlı değildir. Ders 2'deki "Ult hazır mı?" görevinde ultinin 6. seviyede açıldığını yazdın. Ama ulti açık olsa da manan yetmiyorsa R'ye basamazsın. Ahri'nin R yeteneğini kullanabilmesi için iki şart var: en az 6. seviyede olmalı ve en az 100 manası olmalı. İki koşulu tek soruda birleştirmek için mantık işaretleri kullanılır.
&&: ve
const seviye = 7const mana = 80if (seviye >= 6 && mana >= 100) { console.log("R kullanılabilir")} else { console.log("R kullanılamaz")}R kullanılamaz&& iki yanındaki koşulun ikisi de true ise true verir. Burada seviye >= 6 true ama mana >= 100 false. Biri bile false olduğu için sonuç false oldu ve else bloğu çalıştı. & işaretini Türkçe Q klavyede Shift+6 ile yazarsın; arada boşluk bırakmadan iki tane.
||: veya
Kaçmak için Flash ya da Hayalet (Ghost) büyülerinden birinin hazır olması yeter:
const flashHazir = falseconst hayaletHazir = trueif (flashHazir || hayaletHazir) { console.log("Kaçabilirsin")} else { console.log("Kaçış yok, savaş")}Kaçabilirsin|| iki yanından en az biri true ise true verir; ikisi de false ise false. | işareti Türkçe Q klavyede AltGr+- ile yazılır (- tuşu Backspace'in hemen solunda).
Ders 2'de gördüğün gibi, flashHazir gibi zaten true ya da false tutan bir değişkeni koşula doğrudan yazabilirsin. if (flashHazir) ile if (flashHazir === true) aynı anlama gelir; kısa olanı yaygındır.
!: değil
! tek bir koşulun önüne gelir ve onu tersine çevirir: true'yu false, false'u true yapar.
const flashHazir = falseconsole.log(!flashHazir)if (!flashHazir) { console.log("Flash bekleme süresinde")}trueFlash bekleme süresinde!flashHazir "Flash hazır değil" diye okunur. flashHazir false olduğu için !flashHazir true'dur ve blok çalışır. ! işareti Shift+1 ile yazılır. Ders 2'deki !== (eşit değil) işaretinin başındaki ! de aynı "değil" anlamını taşır.
Bir karşılaştırmanın tamamını tersine çevirmek istersen onu parantez içine al:
const mana = 40console.log(!(mana >= 100))trueÖnce parantezin içi hesaplanır (40 >= 100 false), sonra ! onu true yapar. "Mana 100 ya da üstü değil" demek.
Doğruluk tablosu
Bütün durumlar tek tabloda (a ve b herhangi iki koşul):
a | b | a && b | a || b |
|---|---|---|---|
| true | true | true | true |
| true | false | false | true |
| false | true | false | true |
| false | false | false | false |
!true false, !false true verir. Tabloyu ezberlemen gerekmiyor, iki cümle yeter: && hepsini ister, || en az birini. Emin olamadığında kendin dene:
console.log(true && true)console.log(true && false)console.log(false || true)console.log(false || false)console.log(!true)truefalsetruefalsefalse&& arka arkaya iki kapıdır, ikisi de açık olmalı. || yan yana iki yoldur, biri açıksa geçersin. Kapılardaki değerler yukarıdaki iki örnekten.Fonksiyon: bir kez yaz, istediğin kadar çalıştır
Şampiyon her öldüğünde ekrana aynı iki satırı yazdırmak istiyorsun: "Üste doğdun" ve "Can ve mana doldu". Maç boyunca on kez ölürsen bu iki satırı on kez kopyalaman gerekir. Sonra mesajı değiştirmek istersen on kopyayı tek tek bulup düzeltmen gerekir; birini unutursan program tutarsız olur.
Çözüm, o satırları bir kez yazıp onlara bir ad vermek, sonra her ihtiyaç duyduğunda yalnızca o adı söylemek. Adı olan böyle bir kod parçasına fonksiyon denir.
Tanımlamak
function yenidenDog() { console.log("Üste doğdun") console.log("Can ve mana doldu")}Parçaları:
function: "bir fonksiyon tanımlıyorum" diyen anahtar sözcük. Hep küçük harfle yazılır.yenidenDog: fonksiyonun adı. Değişken adlarıyla aynı kurallara uyar: camelCase, İngilizce harfler.(): parametre parantezi. Şimdilik boş, birazdan içini dolduracağız. Boş olsa bile yazılmak zorunda.{ ... }: fonksiyonun gövdesi (body). Fonksiyon çalıştığında yapılacak işler bu süslü parantezlerin arasına, 4 boşluk içeriden yazılır.{işareti AltGr+7,}işareti AltGr+0 ile yazılır.
Bu dosyayı kaydet ve çalıştır:
function yenidenDog() { console.log("Üste doğdun") console.log("Can ve mana doldu")}PS C:\kod\ogren> node ders3.jsPS C:\kod\ogren> Program hatasız bitti ama ekrana tek satır bile yazmadı. Fonksiyon tanımlandı ama çalıştırılmadı.
Bu, dersin en önemli fikri: tanımlamak çalıştırmak değildir. Bir fonksiyonu tanımladığında JavaScript yalnızca "yenidenDog adında bir iş var, adımları şunlar" diye not alır. Gövdedeki satırlar, biri o işi isteyene kadar bekler.
Çağırmak
Fonksiyonu çalıştırmak için adını yazıp yanına parantez koyarsın: yenidenDog(). Buna fonksiyonu çağırmak denir.
function yenidenDog() { console.log("Üste doğdun") console.log("Can ve mana doldu")} yenidenDog()yenidenDog()Üste doğdunCan ve mana dolduÜste doğdunCan ve mana dolduİki çağrı, iki çalışma. Mesajı değiştirmek istersen artık tek bir yeri, fonksiyonun gövdesini değiştirmen yeter; bütün çağrılar yeni hâliyle çalışır.
Peki çağrı gelince program nereye gider? Çağrının önüne ve arkasına birer satır ekleyip sırayı izleyelim:
function yenidenDog() { console.log("Üste doğdun") console.log("Can ve mana doldu")} console.log("Öldün")yenidenDog()console.log("Koridora dön")ÖldünÜste doğdunCan ve mana dolduKoridora dönProgram hâlâ yukarıdan aşağı çalışıyor; tek fark, çağrı satırında gövdeye gidip geri dönmesi. Ders 1'deki "program yukarıdan aşağı çalışır" kuralını fonksiyon bozmaz, yalnızca araya bir "git ve gel" ekler.
Parametre ve argüman: fonksiyona bilgi vermek
yenidenDog her seferinde aynı şeyi yazıyor. Peki her şampiyonu kendi adıyla selamlamak istersen? ahriyiSelamla, luxuSelamla, gareniSelamla diye ayrı ayrı fonksiyonlar mı yazacaksın? Gerek yok: fonksiyona, çağırırken bilgi verebilirsin.
function selamla(isim) { console.log("Hoş geldin, " + isim)} selamla("Ahri")selamla("Lux")Hoş geldin, AhriHoş geldin, LuxTanımdaki parantezin içindeki isim bir parametredir: fonksiyonun içinde kullanılan ve değeri çağrı anında belli olan bir değişken. Çağrıdaki "Ahri" ise bir argümandır: o çağrıda parametreye konan değer. selamla("Ahri") satırında JavaScript isim kutusuna "Ahri" koyar ve gövdeyi çalıştırır. İkinci çağrıda aynı kutuya bu sefer "Lux" konur.
Birden çok parametre
Parametreleri virgülle ayırarak istediğin kadar ekleyebilirsin. Argümanlar da çağrıda aynı sırayla, virgülle ayrılarak yazılır:
function hasarYaz(isim, hasar) { console.log(isim + " " + hasar + " hasar aldı")} hasarYaz("Garen", 120)hasarYaz("Jinx", 75)Garen 120 hasar aldıJinx 75 hasar aldıEşleşme sıraya göredir: birinci argüman birinci parametreye, ikinci argüman ikinci parametreye gider. JavaScript adlara bakmaz. Sırayı karıştırırsan hata mesajı bile almazsın, yalnızca saçma bir çıktı alırsın:
function hasarYaz(isim, hasar) { console.log(isim + " " + hasar + " hasar aldı")} hasarYaz(120, "Garen")120 Garen hasar aldıBir argümanı vermeyi unutursan o parametrenin kutusu boş kalır. JavaScript bu boşluğa undefined der:
function hasarYaz(isim, hasar) { console.log(isim + " " + hasar + " hasar aldı")} hasarYaz("Garen")Garen undefined hasar aldıFazladan argüman verirsen JavaScript fazlalığı sessizce yok sayar: selamla("Ahri", "Lux") yalnızca Ahri'yi selamlar. Parametre ve argüman sayısını eşit tutmak senin işin.
Fonksiyonun içinde karar
Parametreler gövdede sıradan değişkenler gibi kullanılır: hesaba girer, if koşuluna yazılır. Dersin başındaki derece zincirini bir fonksiyona koyarsan sınır denemesi tek seferde biter:
function dereceYaz(puan) { if (puan >= 2000) { console.log(puan + ": Platin") } else if (puan >= 1500) { console.log(puan + ": Altın") } else if (puan >= 1000) { console.log(puan + ": Gümüş") } else { console.log(puan + ": Bronz") }} dereceYaz(2000)dereceYaz(1999)dereceYaz(1500)dereceYaz(1499)dereceYaz(1000)dereceYaz(999)2000: Platin1999: Altın1500: Altın1499: Gümüş1000: Gümüş999: BronzAltı sınır, altı çağrı, tek çalıştırma. Zincirin sırasını bozarsan hangi satırın değiştiğini hemen görürsün.
Fonksiyonlara ad vermek
Ders 1'de değişkenlere ad verme kurallarını gördün. Fonksiyonlar için de aynısı geçerli, üstüne bir kural daha:
- Fonksiyon bir iş yapar; adı da o işi söylesin. Adı fiille kur:
selamla,hasarYaz,yenidenDog,dereceYaz. - camelCase kullan: ilk sözcük küçük, sonrakilerin ilk harfi büyük.
- Adlarda Türkçe harf kullanma:
hasarYazdırdeğil,hasarYazdir. - Parametrelere de anlamlı ad ver; adları içlerine ne konacağını söylesin.
- Büyük-küçük harf farklıdır.
hasarYazileHasarYaziki ayrı addır. Fonksiyonu tanımladığından farklı harfle çağırırsanReferenceErroralırsın; örneği Sık hatalar bölümünde.
Kötü ve iyi adlar yan yana; her satırın nedeni yukarıdaki maddelerde:
| Kötü ad | İyi ad |
|---|---|
f(a, b) | hasarYaz(isim, hasar) |
islem() | yenidenDog() |
HasarYaz() | hasarYaz() |
hasarYazdır() | hasarYazdir() |
Kendini tekrar etme
Ahri'nin üç yeteneği için "hazır mı" denetimi yapan bir program düşün:
const mana = 90 if (mana >= 60) { console.log("Q: hazır")} else { console.log("Q: mana yetmiyor")} if (mana >= 80) { console.log("W: hazır")} else { console.log("W: mana yetmiyor")} if (mana >= 100) { console.log("R: hazır")} else { console.log("R: mana yetmiyor")}Q: hazırW: hazırR: mana yetmiyorÜç blok neredeyse aynı. Yalnızca iki şey değişiyor: yeteneğin adı (Q, W, R) ve maliyeti (60, 80, 100). Kural şu: değişen parçalar parametre olur, aynı kalan kısım gövdeye girer.
function yetenekDenetle(yetenek, maliyet, mana) { if (mana >= maliyet) { console.log(yetenek + ": hazır") } else { console.log(yetenek + ": mana yetmiyor") }} const ahriMana = 90yetenekDenetle("Q", 60, ahriMana)yetenekDenetle("W", 80, ahriMana)yetenekDenetle("R", 100, ahriMana)Q: hazırW: hazırR: mana yetmiyorÇıktı aynı, kod daha kısa. Son üç satıra dikkat: argüman olarak bir değişken de verebilirsin. yetenekDenetle("Q", 60, ahriMana) çağrısında JavaScript ahriMana kutusunun içindekini (90) alır ve mana parametresine koyar.
Asıl kazanç değişiklik zamanında gelir. "mana yetmiyor" yerine kaç mana eksik olduğunu yazdırmak istersen tek satırı değiştirirsin, üç yetenek birden güncellenir:
function yetenekDenetle(yetenek, maliyet, mana) { if (mana >= maliyet) { console.log(yetenek + ": hazır") } else { console.log(yetenek + ": " + (maliyet - mana) + " mana eksik") }} const ahriMana = 90yetenekDenetle("Q", 60, ahriMana)yetenekDenetle("W", 80, ahriMana)yetenekDenetle("R", 100, ahriMana)Q: hazırW: hazırR: 10 mana eksikKapsam: fonksiyonun içi dışarıdan görünmez
Fonksiyonun içinde bir değişken oluşturup onu dışarıda kullanmayı dene:
function komboHesapla() { let toplam = 120 + 80 + 200 console.log("Kombo hasarı: " + toplam)} komboHesapla()console.log(toplam)Kombo hasarı: 400C:\kod\ogren\ders3.js:7console.log(toplam) ^ ReferenceError: toplam is not defined at Object.<anonymous> (C:\kod\ogren\ders3.js:7:13) ... Node.js v24.20.0Fonksiyon çalıştı ve içeride toplam sorunsuz kullanıldı. Ama 7. satırda, fonksiyonun dışında JavaScript toplam diye bir kutu bulamadı.
Sebebi şu: toplam fonksiyonun gövdesinde let ile açıldı (const ile açılsaydı da aynısı olurdu). O kutu yalnızca gövdenin içinde yaşar ve fonksiyon bitince kaldırılır. Bir değişkenin kullanılabildiği bu bölgeye kapsam denir.
Parametreler de böyledir: selamla(isim) tanımındaki isim yalnızca selamla fonksiyonunun içinde vardır. Dışarıda console.log(isim) yazarsan aynı hatayı bu sefer isim is not defined diye alırsın.
Ters yönde ise yol açık: fonksiyonun içi, dışarıda oluşturulmuş değişkenleri görür.
const oyuncu = "Ahri" function selamla() { console.log("Hoş geldin, " + oyuncu)} selamla()Hoş geldin, AhriBu bir kısıtlama gibi görünse de işine yarar: her fonksiyon kendi kutularını kullanır, başka fonksiyonlarla karışmaz. İki ayrı fonksiyonda toplam adlı birer değişken olabilir ve birbirlerinin değerini bozmazlar.
İçerideki bir değeri dışarıda kullanman gerekiyorsa şimdilik işi fonksiyonun içinde bitir: yazdırma satırını gövdeye taşı. Değeri dışarı çıkarmanın doğru yolu return; Ders 6'da.
Sık hatalar
Bu derste karşılaşabileceğin hatalar. Bütün derslerin hataları hata rehberinde toplanıyor.
SyntaxError: Unexpected token '}' (süslüyü hemen kapatmak)Ne zaman çıkar? Fonksiyonun süslü parantezini ilk satırda hemen kapatıp gövdeyi altına yazınca. Gövde sandığın satırlar fonksiyonun dışında kalır, en sondaki } işareti de fazla gelir.
function durumYaz(isim, hp) {} console.log(isim + " canı: " + hp)} durumYaz("Ahri", 100)C:\kod\ogren\ders3.js:3}^ SyntaxError: Unexpected token '}' at wrapSafe (node:internal/modules/cjs/loader:1861:18) ... Node.js v24.20.0Nasıl düzelir? Mesaj 3. satırdaki } işaretini gösteriyor ama asıl hata 1. satırda: {} yan yana yazılmış. Açılış süslüsü 1. satırın sonunda kalsın, kapanışı gövdenin altına gelsin. VS Code'da imleci bir süslünün yanına koyunca eşi vurgulanır; eşi beklediğin yerde değilse hata oradadır.
Sondaki } işaretini silmek çözüm değil: bu mesaj gider ama yerine ReferenceError: isim is not defined gelir. Gövde sandığın satır fonksiyonun dışında çalışır ve orada isim diye bir kutu yoktur.
Ne zaman çıkar? Fonksiyonu tanımlayıp hiç çağırmayınca. Program hatasız biter ama ekrana hiçbir şey yazmaz; yukarıdaki VS Code penceresinde gördüğün durum.
Nasıl düzelir? Tanımın altına çağrıyı ekle: yenidenDog(). Fonksiyon tanımı bir tarif gibidir; biri istemedikçe çalışmaz.
[Function: durumYaz]Ne zaman çıkar? Fonksiyonu çağırırken parantezleri unutunca. Tek başına durumYaz yazmak fonksiyonu yalnızca anar, çalıştırmaz. Program sessizce devam eder:
function durumYaz(isim, hp) { console.log(isim + " canı: " + hp)} durumYaz Fonksiyonun adını console.log içine yazarsan çağrı yerine fonksiyonun kendisi yazdırılır:
function durumYaz(isim, hp) { console.log(isim + " canı: " + hp)} console.log(durumYaz)[Function: durumYaz][Function: durumYaz] "bu bir fonksiyon, adı durumYaz" demek: tarifin kendisi, pişmiş yemek değil.
Nasıl düzelir? Çağrıyı adla ve parantezle yaz, argümanları da ver: durumYaz("Ahri", 100). Çıktında [Function: …] görürsen bir yerde parantezi unuttun demektir.
ReferenceError: DurumYaz is not definedNe zaman çıkar? Fonksiyonu tanımladığından farklı harflerle çağırınca. Büyük-küçük harf de farklılık sayılır.
function durumYaz(isim, hp) { console.log(isim + " canı: " + hp)} DurumYaz("Ahri", 100)C:\kod\ogren\ders3.js:5DurumYaz("Ahri", 100)^ ReferenceError: DurumYaz is not defined at Object.<anonymous> (C:\kod\ogren\ders3.js:5:1) ... Node.js v24.20.0Nasıl düzelir? Çağrıdaki adı tanımdakiyle harfi harfine aynı yaz. VS Code yazarken fonksiyonun adını önerir; öneriyi Enter ile seçersen bu hatayı yapmazsın.
undefined varNe zaman çıkar? Fonksiyonu çağırırken bir argümanı vermeyi unutunca. Hata mesajı çıkmaz; eksik parametrenin yerine undefined yazılır.
function durumYaz(isim, hp) { console.log(isim + " canı: " + hp)} durumYaz("Ahri")Ahri canı: undefinedNasıl düzelir? Tanımdaki parametreleri say, çağrıda o kadar argüman ver: durumYaz("Ahri", 100). Argümanların sırası da parametrelerinkiyle aynı olmalı.
SyntaxError: Unexpected token '{' (bitişik elseif)Ne zaman çıkar? else if sözcüklerini bitişik (elseif) yazınca. Aynı mesajı Ders 2'de else sözcüğüne koşul yazınca da görmüştün; ısınmadaki if (mana > 10 { satırı da bu mesajı verir.
const puan = 1200if (puan >= 2000) { console.log("Platin")} elseif (puan >= 1000) { console.log("Gümüş")}C:\kod\ogren\ders3.js:4} elseif (puan >= 1000) { ^ SyntaxError: Unexpected token '{' at wrapSafe (node:internal/modules/cjs/loader:1861:18) ... Node.js v24.20.0Nasıl düzelir? JavaScript elseif diye bir sözcük tanımaz. elseif (puan >= 1000) kısmını elseif adlı bir fonksiyonun çağrısı sanır ve hemen ardından gelen { işaretinde takılır. else ile if arasına boşluk koy. Koşul gerekiyorsa else yerine else if yaz; tek başına else koşul almaz. VS Code bu satırın altını çalıştırmadan önce kırmızıyla çizer; fareyle üstüne gelirsen açıklama olarak ';' expected. yazar.
SyntaxError: Unexpected token 'else' (else'ten sonra else if)Ne zaman çıkar? else bloğundan sonra bir else if daha yazınca. else "geri kalan her şey" demektir, zincirin son halkasıdır.
const puan = 1200if (puan >= 2000) { console.log("Platin")} else { console.log("Bronz")} else if (puan >= 1000) { console.log("Gümüş")}C:\kod\ogren\ders3.js:6} else if (puan >= 1000) { ^^^^ SyntaxError: Unexpected token 'else' at wrapSafe (node:internal/modules/cjs/loader:1861:18) ... Node.js v24.20.0Nasıl düzelir? else if bloklarını else bloğunun üstüne taşı. Sıra hep aynıdır: if, sonra istediğin kadar else if, en son (istersen) else.
SyntaxError: Unexpected token '<='Ne zaman çıkar? Aralık sorarken ikinci karşılaştırmanın sol yanındaki adı yazmayınca.
const puan = 1200if (puan >= 1000 && <= 1499) { console.log("Gümüş")}C:\kod\ogren\ders3.js:2if (puan >= 1000 && <= 1499) { ^^ SyntaxError: Unexpected token '<=' at wrapSafe (node:internal/modules/cjs/loader:1861:18) ... Node.js v24.20.0Nasıl düzelir? && iki tam koşulu bağlar; her koşulun iki yanı da dolu olmalı: puan >= 1000 && puan <= 1499. Konuşurken "1000'den büyük ve 1499'dan küçük" deriz, ama JavaScript'e "puan 1000'den büyük ve puan 1499'dan küçük" demek zorundasın.
ReferenceError: toplam is not defined (fonksiyonun içindeki değişken)Ne zaman çıkar? Bir fonksiyonun içinde oluşturduğun bir değişkeni ya da bir parametreyi fonksiyonun dışında kullanınca. Örneğini kapsam bölümünde gördün.
Nasıl düzelir? O değeri kullanan satırı fonksiyonun gövdesine taşı. "Ama ben bu değişkeni oluşturdum" diyorsan, nerede oluşturduğuna bak: başka bir fonksiyonun içindeyse buradan görünmez.
SyntaxError: Unexpected stringNe zaman çıkar? Tanımın parantezine değer yazınca: function selamla("Ahri"). Tanımla çağrıyı karıştırmak demek bu.
function selamla("Ahri") { console.log("Hoş geldin, Ahri")}C:\kod\ogren\ders3.js:1function selamla("Ahri") { ^^^^^^ SyntaxError: Unexpected string at wrapSafe (node:internal/modules/cjs/loader:1861:18) ... Node.js v24.20.0Nasıl düzelir? Tanımın parantezine yalnızca parametre adları yazılır; değerler çağrıda verilir. Tanımda bir ad kullan, değeri çağrıya taşı: önce function selamla(isim) { ... }, sonra selamla("Ahri").
Görevler
Her görevi ders3.js dosyasında yap; önceki kodu sil ya da satırların başına // koy. Önce kendin dene, takılırsan ipuçlarını sırayla aç. Çözüme en son bak.
Kill duyurusu
İki parametre alan, killDuyur adında bir fonksiyon yaz: birinci parametre kill alan şampiyonun, ikincisi ölen şampiyonun adı olsun. Fonksiyonu üç kez çağırarak şu çıktıyı üret:
Ahri bir kill aldı. Ölen: GarenJinx bir kill aldı. Ölen: TeemoLux bir kill aldı. Ölen: YasuoBitirince son çağrıdaki iki argümanın yerini değiştir ve çıktının nasıl değiştiğine bak.
İpucu 1
Parametrelere ne taşıdıklarını söyleyen adlar ver, örneğin olduren ve olen (Türkçe harf kullanmadan).
İpucu 2
Gövde tek satır: bir console.log. Metinle parametreleri + ile birleştir; " bir kill aldı. Ölen: " metninin başındaki ve sonundaki boşluklara dikkat.
Çözümü göster
function killDuyur(olduren, olen) { console.log(olduren + " bir kill aldı. Ölen: " + olen)} killDuyur("Ahri", "Garen")killDuyur("Jinx", "Teemo")killDuyur("Lux", "Yasuo")Ahri bir kill aldı. Ölen: GarenJinx bir kill aldı. Ölen: TeemoLux bir kill aldı. Ölen: YasuoArgümanların yerini değiştirince (killDuyur("Yasuo", "Lux")) çıktı Yasuo bir kill aldı. Ölen: Lux olur. Program hata vermez ama hikâye tersine döner: argümanlar adla değil, sırayla eşleşir.
Ejderhaya gidelim mi?
Takımın ejderhaya gitmesi için üç şartın hepsi gerekli:
- en az 3 kişi hayatta olmalı,
- ormancının Smite'ı hazır olmalı,
- rakip ormancı görünmüş olmamalı.
Şu üç değişkenle başla ve tek bir if / else yaz. Şartların hepsi tutuyorsa Ejderhaya git!, tutmuyorsa Bekle, şimdi değil yazdırsın:
const canliSayisi = 4const smiteHazir = trueconst rakipGorundu = falseBu değerlerle çıktı Ejderhaya git! olmalı. Sonra sınırları dene: canliSayisi 3 iken yine Ejderhaya git!, 2 iken Bekle, şimdi değil çıkmalı. rakipGorundu değerini true yapınca da Bekle, şimdi değil çıkmalı.
İpucu 1
Üç şartın hepsi gerektiğine göre üç koşulu iki tane && ile bağlayacaksın.
İpucu 2
"Görünmüş olmamalı" bir "değil" cümlesi: !rakipGorundu. smiteHazir zaten true ya da false tuttuğu için koşula doğrudan yazabilirsin.
Çözümü göster
const canliSayisi = 4const smiteHazir = trueconst rakipGorundu = false if (canliSayisi >= 3 && smiteHazir && !rakipGorundu) { console.log("Ejderhaya git!")} else { console.log("Bekle, şimdi değil")}Ejderhaya git!Sınır denemesi: canliSayisi >= 3 yazdığın için 3 kişiyle gidilir, 2 kişiyle gidilmez. canliSayisi > 3 yazsaydın 3 kişiyle de beklerdin. Sınırın tam üstünü ve tam altını ayrı ayrı denemenin sebebi bu.
Şampiyon durumu
Ders 2'nin sınır değerleri bölümünde canı 0 olan bir şampiyona bile "geri çekil" deniyordu; üç durumu birbirinden ayıramıyorduk. Şimdi ayırabilirsin. durumYaz adında, iki parametreli (şampiyonun adı ve canı) bir fonksiyon yaz. Kurallar:
- can 0 ya da daha azsa:
Garen: öldü - can 1 ile 30 arasındaysa (30 dahil):
Lux: tehlikede, geri çekil - can 30'dan fazlaysa:
Ahri: savaşabilir
Fonksiyonu üç şampiyon için sınır değerleriyle çağır: Garen 0, Lux 30, Ahri 31. Çıktı şu olmalı:
Garen: öldüLux: tehlikede, geri çekilAhri: savaşabilirİpucu 1
Gövdede üç dallı bir zincir olacak: if, else if, else.
İpucu 2
İskelet:
function durumYaz(isim, hp) { if (...) { ... } else if (...) { ... } else { ... }}İpucu 3
Sıra önemli. Burada <= kullanıyorsun, o yüzden en küçük sınırdan başla: önce hp <= 0, sonra hp <= 30. Tersini yazarsan Garen'in 0 canı da hp <= 30 sorusundan geçer ve Garen "tehlikede" görünür.
Çözümü göster
function durumYaz(isim, hp) { if (hp <= 0) { console.log(isim + ": öldü") } else if (hp <= 30) { console.log(isim + ": tehlikede, geri çekil") } else { console.log(isim + ": savaşabilir") }} durumYaz("Garen", 0)durumYaz("Lux", 30)durumYaz("Ahri", 31)Garen: öldüLux: tehlikede, geri çekilAhri: savaşabilirSınır denemesi: aşağıdaki iki çağrıyı da ekle. 1 canlı Teemo tehlikede olmalı. Can eksiye de düşebilir (son vuruş kalan candan büyükse), bu yüzden -20 canlı Jinx öldü sayılmalı. hp === 0 yerine hp <= 0 yazmanın sebebi bu.
durumYaz("Teemo", 1)durumYaz("Jinx", -20)Teemo: tehlikede, geri çekilJinx: öldüTekrarı temizle
Aşağıdaki program üç oyuncunun maç karnesini yazıyor. Çalışıyor ama aynı blok üç kez kopyalanmış:
let isim = "Ahri"let kill = 7let olum = 2if (kill > olum) { console.log(isim + " " + kill + "/" + olum + ": maçı taşıdın")} else { console.log(isim + " " + kill + "/" + olum + ": zor bir maçtı")} isim = "Garen"kill = 1olum = 6if (kill > olum) { console.log(isim + " " + kill + "/" + olum + ": maçı taşıdın")} else { console.log(isim + " " + kill + "/" + olum + ": zor bir maçtı")} isim = "Jinx"kill = 4olum = 4if (kill > olum) { console.log(isim + " " + kill + "/" + olum + ": maçı taşıdın")} else { console.log(isim + " " + kill + "/" + olum + ": zor bir maçtı")}Ahri 7/2: maçı taşıdınGaren 1/6: zor bir maçtıJinx 4/4: zor bir maçtı- Programı aynı çıktıyı veren bir fonksiyon ve üç çağrıya çevir. Fonksiyona yaptığı işi anlatan bir ad ver.
- Sonra kuralı değiştir: kill sayısı ölüm sayısına eşitse
başa başyazsın. Jinx'in satırıJinx 4/4: başa başolmalı. Bu değişikliği fonksiyonlu sürümde yap ve kaç yere dokunduğunu say.
İpucu 1
Kopyalarda ne değişiyor? İsim, kill ve ölüm. Bunlar fonksiyonunun üç parametresi olacak.
İpucu 2
Eşitlik için bir else if (kill === olum) dalı ekle. kill > olum ile kill === olum aynı anda true olamaz, bu yüzden ikisinin sırası sonucu değiştirmez; yeter ki ikisi de else bloğundan önce olsun.
Çözümü göster
function karneYaz(isim, kill, olum) { const ozet = isim + " " + kill + "/" + olum if (kill > olum) { console.log(ozet + ": maçı taşıdın") } else if (kill === olum) { console.log(ozet + ": başa baş") } else { console.log(ozet + ": zor bir maçtı") }} karneYaz("Ahri", 7, 2)karneYaz("Garen", 1, 6)karneYaz("Jinx", 4, 4)Ahri 7/2: maçı taşıdınGaren 1/6: zor bir maçtıJinx 4/4: başa başYeni kural için yalnızca fonksiyonun gövdesine bir else if dalı ekledin, üç çağrıya hiç dokunmadın. Kopyalı sürümde aynı işi üç yerde yapacaktın. ozet değişkeni de fonksiyonun içindeki küçük tekrarı temizliyor: isim + " " + kill + "/" + olum artık bir kez yazılıyor. Jinx'in 4/4'ü de sınır değeriydi: eşitlik durumunu ayrıca denemeseydin bu kuralın eksik olduğunu fark etmezdin.
Hata avı
Bu programda dört hata var. Gözle aramadan, yalnızca hata mesajlarını okuyarak düzelt: çalıştır, ilk mesajı oku, o hatayı düzelt, yeniden çalıştır.
function tanit(isim, rol) {} if (rol === "destek") { console.log(isim + " takımını korur") } elseif (rol === "orman") { console.log(isim + " ormanda dolaşır") } else { console.log(isim + " koridorda savaşır") }} Tanit("Lux", "destek")console.log(rol)C:\kod\ogren\ders3.js:4 } elseif (rol === "orman") { ^ SyntaxError: Unexpected token '{' at wrapSafe (node:internal/modules/cjs/loader:1861:18) ... Node.js v24.20.0Hepsini düzeltince çıktı Lux takımını korur olmalı.
İpucu 1
İlk mesaj 4. satırı gösteriyor. { işaretinden önce JavaScript'in tanımadığı bir sözcük var.
İpucu 2
İkinci mesaj Unexpected token '}' olacak ve 9. satırı gösterecek. Bu süslü neyi kapatıyor? Fonksiyonun açılış süslüsünü 1. satırda bul. 9. satırdaki } işaretini silmek işe yaramaz: o zaman 2. satırda ReferenceError: rol is not defined alırsın, çünkü if zinciri fonksiyonun dışında kalır.
İpucu 3
Son iki hata ReferenceError. Biri büyük-küçük harf meselesi, öteki kapsam meselesi: rol hangi fonksiyonun parametresi?
Çözümü göster
function tanit(isim, rol) { if (rol === "destek") { console.log(isim + " takımını korur") } else if (rol === "orman") { console.log(isim + " ormanda dolaşır") } else { console.log(isim + " koridorda savaşır") }} tanit("Lux", "destek")Lux takımını korurSırasıyla gelen mesajlar: SyntaxError: Unexpected token '{' (bitişik elseif), SyntaxError: Unexpected token '}' (1. satırda hemen kapatılan süslü), ReferenceError: Tanit is not defined (büyük T), ReferenceError: rol is not defined (parametre fonksiyonun dışında kullanılmış; o satır silinir). İki SyntaxError önce geldi, çünkü Node yazım hatası olan dosyayı hiç başlatmaz. ReferenceError ise ancak program çalışırken, sırası gelince çıkar.
Sınır denemesi: zincirin öteki iki dalını da dene.
tanit("Nunu", "orman")tanit("Garen", "üst")Nunu ormanda dolaşırGaren koridorda savaşırDükkân görevlisi
Dükkândan eşya alabilmek için iki şart var: üste (base) ya da ölü olmalısın, bir de altının yetmeli. esyaAl adında beş parametreli bir fonksiyon yaz: eşyanın adı, fiyatı, oyuncunun altını, oyuncu üste mi (true ya da false), oyuncu ölü mü (true ya da false). Üç olası sonuç var:
- Oyuncu ne üsteyse ne ölüyse:
Uzun Kılıç alınamadı: dükkân kapalı, önce üsse dön - Dükkân açık ve altın yetiyorsa:
Doran'ın Kılıcı alındı, kalan altın: 50 - Dükkân açık ama altın yetmiyorsa:
Rabadon'un Ölüm Şapkası için 1 altın eksik
Şu dört çağrıyı yap:
esyaAl("Doran'ın Kılıcı", 450, 500, true, false)esyaAl("B. F. Kılıcı", 1300, 1300, false, true)esyaAl("Rabadon'un Ölüm Şapkası", 3600, 3599, true, false)esyaAl("Uzun Kılıç", 350, 2000, false, false)Beklenen çıktı:
Doran'ın Kılıcı alındı, kalan altın: 50B. F. Kılıcı alındı, kalan altın: 0Rabadon'un Ölüm Şapkası için 1 altın eksikUzun Kılıç alınamadı: dükkân kapalı, önce üsse dönİkinci ve üçüncü çağrı sınır değerleri: altın fiyata tam eşit ve fiyattan 1 eksik.
İpucu 1
Üç sonuç var, demek ki üç dallı bir zincir: if, else if, else. Önce dükkânın kapalı olduğu durumu sor; altın hesabına ancak dükkân açıksa sıra gelsin.
İpucu 2
Dükkân, üsteysen ya da ölüysen açık. Bunu gövdenin ilk satırında bir değişkene koy: const dukkanAcik = ustte || olu. Kapalı dükkânı sormak için bu değeri ! ile tersine çevir: if (!dukkanAcik).
İpucu 3
Kalan altın altin - fiyat, eksik altın fiyat - altin. Metnin içinde hesap yaparken parantezi unutma: "kalan altın: " + (altin - fiyat).
Çözümü göster
function esyaAl(esya, fiyat, altin, ustte, olu) { const dukkanAcik = ustte || olu if (!dukkanAcik) { console.log(esya + " alınamadı: dükkân kapalı, önce üsse dön") } else if (altin >= fiyat) { console.log(esya + " alındı, kalan altın: " + (altin - fiyat)) } else { console.log(esya + " için " + (fiyat - altin) + " altın eksik") }} esyaAl("Doran'ın Kılıcı", 450, 500, true, false)esyaAl("B. F. Kılıcı", 1300, 1300, false, true)esyaAl("Rabadon'un Ölüm Şapkası", 3600, 3599, true, false)esyaAl("Uzun Kılıç", 350, 2000, false, false)Doran'ın Kılıcı alındı, kalan altın: 50B. F. Kılıcı alındı, kalan altın: 0Rabadon'un Ölüm Şapkası için 1 altın eksikUzun Kılıç alınamadı: dükkân kapalı, önce üsse döndukkanAcik fonksiyonun içinde açıldığı için yalnızca gövdede yaşar; dışarıda ona ihtiyacın da yok. Kapalı dükkânı değişken kullanmadan !ustte && !olu ("ne üste ne ölü") diye de sorabilirdin, sonuç aynı olurdu. Değişkenin adı ise kuralı okunur kılıyor: "dükkân açık değilse".
altin >= fiyat yazdığın için altın fiyata tam eşitken eşya alınır ve 0 altın kalır. > yazsaydın 1300 altınla 1300'lük eşyayı alamazdın; ikinci çağrı tam bu sınırı denetliyor.
Çağrılara bir daha bak: true, false gibi argümanların ne anlama geldiği, tanıma bakmadan anlaşılmıyor. Beş parametre, akılda tutması zor bir liste. Bir sonraki derste bu bilgileri tek bir kutuda toplayıp bu sorunu çözeceksin.
Kendini sına
Soru 1
Bu program ne yazar?
const kill = 3if (kill >= 5) { console.log("Durdurulamaz")} else if (kill >= 3) { console.log("Katliam")} else if (kill >= 1) { console.log("İlk kan")} else { console.log("Henüz kill yok")}Cevabı göster
Katliam. İlk koşul (3 >= 5) false, ikincisi (3 >= 3) true. İkinci blok çalışır ve zincir orada biter. kill >= 1 de true olurdu ama ona hiç sıra gelmez.
Soru 2
Üç satır sırayla ne yazar?
const seviye = 4const mana = 150console.log(seviye >= 6 && mana >= 100)console.log(seviye >= 6 || mana >= 100)console.log(!(mana >= 100))Cevabı göster
Sırasıyla false, true, false. seviye >= 6 false, mana >= 100 true. && ikisinin de true olmasını ister: false. || birini yeterli bulur: true. Son satırda parantezin içi true, ! onu tersine çevirir: false.
Soru 3
Bu program ne yazar?
function uyar() { console.log("Ejderha 1 dakika içinde doğuyor")} console.log("Maç başladı")Cevabı göster
Yalnızca Maç başladı. uyar tanımlandı ama hiç çağrılmadı, bu yüzden gövdesi çalışmadı. Uyarının da çıkması için bir uyar() satırı gerekir.
Soru 4
Hangileri parametre, hangileri argüman?
function iyiles(isim, miktar) { console.log(isim + " " + miktar + " can kazandı")} iyiles("Annie", 80)Cevabı göster
isim ve miktar parametredir: tanımda, parantezin içinde duran adlar. "Annie" ve 80 argümandır: çağrıda verilen değerler. Çağrı anında isim kutusuna "Annie", miktar kutusuna 80 konur ve ekrana Annie 80 can kazandı yazılır.
Soru 5
Bu program bir satır yazıp hata veriyor. Hangi satırda, neden?
function satinAl(altin, fiyat) { const kalan = altin - fiyat console.log("Satın alındı")} satinAl(1300, 450)console.log(kalan)Cevabı göster
Önce Satın alındı yazılır, sonra 7. satırda ReferenceError: kalan is not defined çıkar. kalan fonksiyonun içinde const ile açıldı; kapsamı fonksiyonun gövdesi, dışarıdan görünmez. Düzeltmek için kalan altını gövdenin içinde yazdır: console.log("Satın alındı, kalan altın: " + kalan). Dışarıdaki satırı da sil.
Soru 6
selamla, selamla() ve console.log(selamla) arasındaki fark ne?
Cevabı göster
selamla() fonksiyonu çağırır, gövdesi çalışır. Tek başına selamla fonksiyonu yalnızca anar, çalıştırmaz; hiçbir şey olmaz. console.log(selamla) fonksiyonu çalıştırmadan kendisini yazdırır: [Function: selamla]. Kısacası parantez "şimdi çalıştır" demektir.
Soru 7
Bu iki çağrı aynı şeyi mi yazar?
function hasarYaz(isim, hasar) { console.log(isim + " " + hasar + " hasar aldı")} hasarYaz("Teemo", 50)hasarYaz(50, "Teemo")Cevabı göster
Hayır. İlki Teemo 50 hasar aldı, ikincisi 50 Teemo hasar aldı yazar. Argümanlar parametrelere adlarına göre değil, sırayla eşleşir; ikinci çağrıda isim kutusuna 50, hasar kutusuna "Teemo" girer.
Kayıt noktası
Ders 1'de git init ile klasöründe Git'i başlatmıştın; bunu bir daha yapmana gerek yok. Bu dersin işini kaydetmek için iki komut yeter. VS Code terminalinde, C:\kod\ogren klasöründeyken:
nothing added to commit but untracked files presentNe zaman çıkar? git add . adımını atlayıp doğrudan git commit yazınca. Git yeni dosyayı görüyor, ama onu kayda eklemesini henüz istemedin.
PS C:\kod\ogren> git commit -m "Ders 3: else if, mantık işaretleri ve fonksiyonlar"On branch masterUntracked files: (use "git add <file>..." to include in what will be committed) ders3.js nothing added to commit but untracked files present (use "git add" to track)Nasıl düzelir? Mesajın son satırı ne yapacağını söylüyor: önce git add ., sonra git commit komutunu yeniden çalıştır. Untracked "izlenmeyen" demek: Git bu dosyayı henüz takip etmiyor.
Bir sonraki derste bir şampiyonun adını, canını ve altınını tek bir kutuda toplamayı öğreneceksin: obje; esyaAl gibi uzun parametre listeleri de böylece tek bir argümana inecek.