Menu

JavaScript Söz Dizimi ve Noktalı Virgül: ASI Kuralları

JavaScript söz dizimi nasıl çalışır — ifadeler, bloklar, expression'lar — ve noktalı virgül meselesinin aslı: otomatik noktalı virgül ekleme (ASI) ne zaman başınızı ağrıtır?

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.

index.js
Output
Click Run to see the output here.

Üç 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.

index.js
Output
Click Run to see the output here.

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 + 3 bir expression'dır. Sonucu 5 olarak 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ı undefined dö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.
index.js
Output
Click Run to see the output here.

Ç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:

index.js
Output
Click Run to see the output here.

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:

index.js
Output
Click Run to see the output here.

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:

index.js
Output
Click Run to see the output here.

Ya da noktalı virgül kullanmayan bir stil tercih ediyorsan, riskli satırın başına bir noktalı virgül koyabilirsin:

index.js
Output
Click Run to see the output here.

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:

index.js
Output
Click Run to see the output here.

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:

index.js
Output
Click Run to see the output here.

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:

  1. Her statement'ın sonuna noktalı virgülü açıkça yaz.
  2. if, for, while, fonksiyon tanımları veya class gövdelerindeki kapanış } işaretinden sonra noktalı virgül koyma.
  3. Bir değişkene atanan object literal veya fonksiyon ifadesi için kapanış } işaretinden sonra koy: const f = function() {};.
  4. 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.
index.js
Output
Click Run to see the output here.

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, username ve UserName birbirinden tamamen farklı üç tanımlayıcıdır.
  • Tanımlayıcılar harf, rakam, _ ve $ içerebilir; ancak rakamla başlayamaz. Ayrıca class, return veya function gibi ayrılmış kelimeler tanımlayıcı olarak kullanılamaz.
index.js
Output
Click Run to see the output here.

$ 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.

Coddy ile kodlamayı öğren

BAŞLA