JavaScript kodu aslında bir dizi statement'tan ibarettir
Bir JavaScript programı, baştan sona sırayla çalıştırılan statement'lardan (ifadelerden) oluşan bir listedir. Değişken tanımlamak bir statement'tır. Bir fonksiyon çağırmak bir statement'tır. if ya da for bloğu da bir statement'tır. Statement'lar birbirinden noktalı virgülle ayrılır.
Üç ifade, üç noktalı virgül. Motor önce birinciyi, sonra ikinciyi, ardından üçüncüyü çalıştırır. Bu kadar basit.
Boşluklar ve girintiler parser için hiçbir anlam taşımaz. Üçünü tek satıra koyup aralarına noktalı virgül bıraksan da kod birebir aynı şekilde çalışır. Girinti kullanmamızın sebebi motor değil, kodu okuyan insan.
Bloklar ifadeleri bir arada gruplar
Süslü parantezler { } bir blok oluşturur; yani motorun tek bir birim gibi değerlendirdiği ifade grubunu. Blokları her yerde göreceksin: fonksiyon gövdeleri, if dalları, döngü gövdeleri.
Süslü parantezlerin içindeki iki console.log çağrısı, if bloğunun gövdesini oluşturuyor. Kapanan } işaretinden sonra noktalı virgül olmadığına dikkat edin — bloklar, sonlandırılması gereken statement'lar değildir. if ifadesi, blok bittiğinde bir bütün olarak sona erer.
Bu durum, her } sonrasına ; koymaya alışık olduğu başka dillerden gelenleri tökezletebiliyor. JavaScript'te ise tek başına duran bir blok ya da kontrol akışı bloğu noktalı virgül istemez.
Expression ve Statement Arasındaki Fark
Erkenden netleştirmekte fayda olan bir ayrım var: expression'lar bir değer üretir, statement'lar ise bir iş yapar.
2 + 3bir expression'dır. Sonucu5olarak hesaplanır.let x = 2 + 3;bir statement'tır. Bir değişken tanımlar ve expression'ın sonucunu ona atar.console.log("hi")bir expression'dır (fonksiyon çağrısıundefineddöndürür), ama kendi başına bir satıra yazılıp sonuna noktalı virgül konduğunda expression statement'a dönüşür.
Çoğu zaman bunu kafaya takmanıza gerek kalmaz. Ama arrow function'larla, ternary ifadelerle ya da JavaScript'in expression beklediği yerde statement vermeye çalıştığınızda (ya da tam tersinde) bu konu önem kazanır.
JavaScript'te noktalı virgül meselesi
Dürüst cevap şu: JavaScript'in Automatic Semicolon Insertion (ASI) denen bir özelliği var ve çoğu satır sonunda eksik noktalı virgülleri sizin yerinize otomatik olarak ekliyor. Yani aşağıdaki gibi bir kod sorunsuz çalışır:
Noktalı virgülsüz de hata almıyorsunuz. ASI her satır sonuna bakıp şunu soruyor: "Bir sonraki token, mevcut ifadenin devamı olabilir mi?" Cevap hayırsa, noktalı virgülü kendisi yerleştiriyor.
ASI sayesinde pratikte iki geçerli stil bir arada yaşıyor:
- Her yerde noktalı virgül. Kod tabanlarının, öğreticilerin ve stil rehberlerinin büyük çoğunluğu böyle yapıyor.
- Noktalı virgülsüz. Bazı modern projeler (Standard stili, bazı React kod tabanları) bu yolu tercih ediyor. ASI'ye ve bir-iki savunma amaçlı numaraya güveniyor.
İkisi de çalışıyor. Hiçbiri "yanlış" değil. Asıl yanlış olan, tutarsızlık — aynı dosyada iki stili karıştırmak, hataları gözden kaçırmayı kolaylaştırıyor.
ASI'nin Sizi Yaktığı Yerler
ASI zamanın yaklaşık %99'unda doğru şeyi yapıyor. Kalan %1 ise, bir önceki satırın devamı gibi görünebilecek bir token'la başlayan satırlardan geliyor. Baş belaları şunlar: [, (, `, +, - ve /.
Şuna bir bakın:
x ve y değişkenlerinin yer değiştirmesini beklersin. Ama ASI, [x, y] ifadesinden önce noktalı virgül eklemez çünkü 10[x, y] söz dizimsel olarak geçerli bir ifadedir (yani 10 sayısının içine indeksleme). Parser 2. satırla 3. satırı tek bir büyük ifade gibi okur; sonuçta ya çalışma zamanı hatası alırsın ya da anlamsız bir çıktı.
Çözüm ya 2. satırın sonuna bir noktalı virgül koymaktır:
Ya da noktalı virgül kullanmayan bir stil tercih ediyorsan, riskli satırın başına bir noktalı virgül koyabilirsin:
Baştaki ; işareti, noktalı virgül kullanmayan projelerin başvurduğu savunma amaçlı bir numaradır. Nedenini bilmeyince tuhaf görünür, ama öğrenince mantıklı geliyor.
return Tuzağı
ASI'nin bir durumu var ki, mutlaka aklınızda kalsın — çünkü sessiz sedasız hatalara yol açıyor. return ifadesinden hemen sonra satır başı yaparsanız, ASI oraya bir noktalı virgül yerleştirir ve fonksiyon undefined döndürür:
Yazar aslında bir nesne döndürmek istiyordu. Ama ASI, satırın sonundaki return ifadesini görüp statement'ı oracıkta sonlandırdı. Dolayısıyla nesne literal'i erişilemez koda dönüştü.
Çözüm basit: değeri return ile aynı satırda başlatmak:
Aynı kural throw, break, continue ve yield için de geçerli — anahtar kelime ile değeri arasına satır sonu koyma.
İşe Yarayan Basit Bir Kural
Eğer yeni başlıyorsan, en kolay yol şu:
- Her statement'ın sonuna noktalı virgülü açıkça yaz.
if,for,while, fonksiyon tanımları veya class gövdelerindeki kapanış}işaretinden sonra noktalı virgül koyma.- Bir değişkene atanan object literal veya fonksiyon ifadesi için kapanış
}işaretinden sonra koy:const f = function() {};. - Bir formatter kullan (Prettier ya da stil kuralı olan ESLint) ve bu konuyu kafandan çıkar. Formatter, takımının kararlaştırdığı her neyse onu uygular.
Bu kural evrensel bir yasa değil — sadece okuyacağınız JavaScript kodlarının büyük çoğunluğunda göreceğiniz bir konvansiyon. Aksini yapmak için sağlam bir gerekçeniz olmadıkça bu kurala bağlı kalın.
Büyük-küçük harf duyarlılığı ve tanımlayıcılar
Buraya iki küçük kural daha sığıyor:
- JavaScript büyük-küçük harfe duyarlıdır.
userName,usernameveUserNamebirbirinden tamamen farklı üç tanımlayıcıdır. - Tanımlayıcılar harf, rakam,
_ve$içerebilir; ancak rakamla başlayamaz. Ayrıcaclass,returnveyafunctiongibi ayrılmış kelimeler tanımlayıcı olarak kullanılamaz.
$ işareti de geçerli bir karakter, ama genelde kütüphanelere özel bir şey olarak ayrılmış durumda (jQuery tarihsel olarak bunu kullanıyordu, bazı template sistemleri hâlâ kullanıyor). Kendi değişkenlerinizde pek tercih etmezsiniz.
Sırada: Strict Mode
Modern JavaScript, sessiz sedasız dilin strict mode adı verilen daha sıkı bir varyantında çalışır; bu mod, gevşek davranışların bir kısmını gerçek hatalara dönüştürür. ES modülleri ve sınıf gövdeleri varsayılan olarak strict çalışır, ama bunun tam olarak neleri değiştirdiğini bilmekte fayda var — bir sonraki sayfanın konusu bu.
Sıkça Sorulan Sorular
JavaScript'te noktalı virgül zorunlu mu?
Teknik olarak hayır — JavaScript'in Automatic Semicolon Insertion (ASI) özelliği çoğu satır sonunda noktalı virgülü sizin yerinize ekler. Ama pratikte ekiplerin büyük kısmı yine de açıkça yazar, çünkü ASI'nin bazı sinsi durumları var: [, (, `, +, -, / ile başlayan satırlarda yanlış yorum yapabiliyor. Bir stil seçin ve Prettier gibi bir formatter'a bırakın işi.
JavaScript'te Automatic Semicolon Insertion (ASI) nedir?
ASI, bir sonraki token mevcut ifadenin devamı olamayacağı durumlarda JavaScript'in satır sonuna noktalı virgülü otomatik eklemesini sağlayan kuraldır. let x = 1 satırının noktalı virgülsüz çalışmasının sebebi budur. Ama bir satır önceki satırın devamı olabilecek bir şeyle — mesela [ veya ( ile — başlıyorsa ASI devreye girmez ve JavaScript iki satırı sessizce birleştirip birbirine yapıştırır.
JavaScript'te bir ifadenin (statement) temel söz dizimi nasıldır?
Statement dediğimiz şey bir talimattır — bir değişken tanımı, fonksiyon çağrısı, if bloğu ya da döngü. Statement'lar birbirinden noktalı virgülle ayrılır (ister açıkça yazın, ister ASI eklesin). Birden fazla statement'ı bir arada tutmak için { } kullanılır. Motor için boşluk ve girinti fark etmez; formatlama tamamen insan gözü içindir.