Okunabilir JavaScript: Yeni Söz Dizimi Ne Zaman Kazandırır
JavaScript'te uzmanlığın ölçüsü olarak çoğu zaman dilin kaç özelliğini bildiğiniz öne sürülür. Oysa aynı işi yapan beş ayrı yazımdan hangisini seçtiğiniz, kodu altı ay sonra devralacak kişi açısından bilginin kendisinden daha belirleyici. Yeni söz dizimi bazen okunabilirliği gerçekten artırır, bazen de sessizce düşürür; aradaki fark göründüğü kadar stil meselesi değil.
Peki hangi bilgi işe yarıyor?
Ekiplerde iki tür deneyimli geliştirici görürsünüz. Biri dilin sunduğu her özelliği kullanmayı ustalığın kanıtı sayar, diğeri aynı özellikleri bilir ama çoğunu kullanmamayı seçer. İkisinin bilgisi eşit, çıktısı değil. Bir satır kod bir kez yazılır, ömrü boyunca onlarca kez okunur; ikinci tavrın neden daha ucuza geldiği bu asimetriden çıkıyor.
flat() gerçek bir kazanç, ama sandığınız kadar değil
Son yıllarda ECMAScript'e eklenen bazı metotlar, eskiden döngüyle yazılan işi tek satıra indiriyor. Array.prototype.flat() bunların en temizi:
let arr = [1, 2, [3, 4]]; arr.flat(); // [1, 2, 3, 4]Kodu ilk kez gören biri bile ne yaptığını anlıyor. Yalnız burada söylenmeyen bir varsayım var: flat() varsayılan olarak tek seviye açar.
[1, [2, [3]]].flat(); // [1, 2, [3]] [1, [2, [3]]].flat(Infinity); // [1, 2, 3]"Diziyi düzleştirir" cümlesi bu ayrımı gizliyor. Metodun okunabilirliğe katkısı, ne yaptığının doğru anlaşılmasına bağlı; yanlış anlaşılan kısa kod, uzun koddan daha pahalı.
Aynı işin beş yazımı
Bir dizinin elemanlarını ikiyle çarpmak için elinizde en az beş seçenek var:
const arr = [1, 2, 3]; let a = arr.map(el => el * 2); let b = arr.map((el) => el * 2); let c = arr.map((el) => { return el * 2; }); let d = arr.map(function (el) { return el * 2; }); const timesTwo = (el) => el * 2; let e = arr.map(timesTwo);Beşi de aynı sonucu üretir, dolayısıyla soru "hangisi doğru" değil, "ekipte hangisi tartışma çıkarmıyor". Bu tür stil tartışmalarını genelde depoya konan tek bir biçimlendirici ayarıyla kapatırım, sonrasında kod incelemesinde parantez konuşmam; incelemede konuşulacak şey isimlendirme ve sınır durumları.
Son yazımın ayrı bir yan etkisi de var. map, geri çağırdığı fonksiyona üç argüman geçirir: eleman, indeks ve dizinin kendisi. timesTwo tek argüman aldığı için sorun çıkmaz, ama aynı yere hazır bir fonksiyon koyduğunuzda sessizce bozulabilir:
['1', '2', '3'].map(parseInt); // [1, NaN, NaN]Burada indeks, parseInt'in taban parametresine düşüyor. Fonksiyonu isimlendirip dışarı almak okunabilirliği artırır, fakat imzayı görünmez kılar.
Yeni olan her zaman daha açık değil
Karşı örnek, destructuring'in şu biçimi:
let node; ({node} = exampleObject);Buradaki parantezler süs değil. Satır { ile başlarsa ayrıştırıcı onu blok sanır, bu yüzden ifadeyi paranteze almak zorunludur. Bir de önceki satırın sonundaki noktalı virgül var; onu silerseniz JavaScript iki satırı birleştirir ve kodu node(...) çağrısı olarak okur, hata da çalışma anında gelir. Yani iki ayrı tuzağı olan bir yazımla, düz atamayla yapılabilecek bir işi yapıyorsunuz:
let node; node = exampleObject.node;Peki destructuring hiç mi kazanmıyor? Kazanıyor, ama tanımla birlikte yazıldığında ve birden çok alan çıkarırken: const {node, parent} = exampleObject; Bu biçimde ne paranteze ne de noktalı virgül nöbetine ihtiyaç var. Sorun söz diziminin kendisinde değil, önce tanımlayıp sonra atama alışkanlığında.
Kodu okuyacak olan insan
Kodunuza bakacak kişiler yalnızca JavaScript'e hakim geliştiriciler olmayabilir; hata ararken bir arka uç geliştiricisi, bir tasarımcı ya da ekibe yeni katılan biri de aynı dosyayı açacak. Fonksiyon adının ne yaptığını söylemesi, bu okuyucuların hepsine aynı anda yarayan tek müdahale.
Yaygın olan söz dizimi de aynı işi görüyor. Spread operatörü güçlü, ama iki diziyi birleştirdiğini anlamak için önce operatörü tanımanız gerekir; concat() adını söylüyor. Bu, spread kullanmayın demek değil: birleştirme dışında bir iş yapıyorsanız spread zaten daha temiz. Ölçü, okuyanın kodu zihninde çalıştırmak zorunda kalıp kalmaması.
Kaynaklar