Menu

JavaScript Console ve DevTools ile Debug Rehberi

Her yere console.log serpiştirmek yerine JavaScript hatalarını çok daha hızlı ayıklamanı sağlayan console metotları ve DevTools özellikleri.

Sadece log'dan İbaret Değil: JavaScript Console'un Tamamı

console.log, çoğu geliştiricinin öğrendiği ilk hata ayıklama aracıdır ve çoğu kişinin asla bırakamadığı bir alışkanlığa dönüşür. İşini görüyor, evet; ama console nesnesinin, hata ayıklamayı çok daha hızlı ve anlaşılır hale getiren bir düzine başka metodu daha var. Üstelik Chrome DevTools'un asıl gücüne — breakpoint'lere, çağrı yığınına (call stack), watch ifadelerine — alışmaya başladığında, log'a eskisi kadar sık başvurmadığını fark edeceksin.

Önce kısa bir turla başlayalım:

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

Dördü de aynı konsola yazar ama tarayıcılar her birini farklı stilize eder: uyarıların arka planı sarı, hataların arka planı kırmızıdır ve yanında bir ikonla birlikte stack trace gelir. DevTools'daki filtreler sayesinde her seviyeyi ayrı ayrı gizleyebilir ya da sadece birine odaklanabilirsin — bir uygulama yüzlerce log basmaya başlayınca bunun kıymetini anlıyorsun.

Birden Fazla Değeri Tembel Yöntemle Loglamak

Aynı anda birkaç değişkeni görmek istediğinde onları string olarak birleştirmeye uğraşma. Ayrı argümanlar olarak geçir — ya da daha iyisi, bir objeye sarmala ki her biri etiketli gelsin:

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

{ user, count } hilesi, nesne kısa yazımından (object shorthand) faydalanıyor: değişken adı otomatik olarak anahtar oluyor. Konsolda { user: {...}, count: 3 } şeklinde görünüyor; user'ı genişletip içine bakabiliyorsun. Üstelik nesneyi stringify ederek yapısını kaybetmiyorsun.

Nesne dizileri için console.table kullanımı

Elinde bir nesne dizisi varken console.log sana iç içe geçmiş, okunması zor bir çıktı verir. Oysa console.table, aynı veriyi düzgün bir tablo olarak karşına getirir:

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

Tarayıcı konsolunda ilk çağrı, sıralanabilir sütunlarla üç satırın tamamını yazdırır. İkinci çağrı ise görünümü yalnızca name ve role ile sınırlar. Veri yapısındaki her şey için (API yanıtları, sorgu sonuçları, parse edilmiş CSV'ler) hayatı fena halde kolaylaştıran bir özellik.

console.dir ile console.log farkı

İlk bakışta benzer görünürler ama DOM elementleri söz konusu olduğunda davranışları farklıdır:

const el = document.querySelector("button");

console.log(el);   // HTML'i yazdırır: <button>Click me</button>
console.dir(el);   // Tüm özellikleriyle birlikte JS nesne görünümünü yazdırır

log elementleri HTML olarak biçimlendirip gösterir. dir ise sana nesnenin kendisini verir — tüm özellikleri, event handler'ları ve hesaplanmış stil referanslarıyla birlikte. Bir elementin hangi metotlara ya da niteliklere sahip olduğunu merak ettiğinde işine yarayacak olan console.dir kullanımıdır.

İlgili çıktıları gruplamak

Uzun süren hata ayıklama seanslarında konsol kısa sürede gürültüye boğulur. İşte tam bu noktada console.group ve console.groupEnd, ilgili mesajları katlanabilir tek bir blok hâlinde toparlamanı sağlar:

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

Her çağrı, daraltabileceğiniz isimli bir grup oluşturur. Grupların varsayılan olarak kapalı başlamasını istiyorsanız console.groupCollapsed kullanın — sadece şüpheli görünenleri açmak istediğinizde oldukça kullanışlıdır.

console.time ile performans ölçümü

Hızlı performans kontrolleri için console.time ve console.timeEnd ikilisinin üstüne yok:

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

time ile timeEnd içindeki etiketlerin birebir aynı olması gerekiyor. Farklı etiketler kullanarak aynı anda birden fazla zamanlayıcı da çalıştırabilirsiniz. Ama "bu döngü yavaş mı acaba?" seviyesinin ötesine geçecekseniz, DevTools'taki Performance paneline geçin; tam bir zaman çizelgesi ve flame chart çıkarıyor.

Assertion kullanımı: Yalnızca bir şeyler ters gittiğinde logla

console.assert, yalnızca koşul falsy olduğunda çıktı verir. Her şey yolundayken konsolu boğmadan kodunuzda sessiz sessiz duran sağlık kontrolleri bırakmanın güzel bir yolu:

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

Değişmez olması gereken koşullar için biçilmiş kaftan. Ama gerçekten başarısız olabilecek durumlar için uygun değil — onlarda düpedüz hata fırlatmak gerekir.

İstek Üzerine Çağrı Yığını (Stack Trace)

console.trace, herhangi bir hata fırlatmadan mevcut çağrı yığınını yazdırır. Bir fonksiyonu kimin çağırdığını anlamaya çalışırken çok işe yarar:

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

Çıktıda inner → outer → (top level) sırasını görürsünüz. Gerçek bir projede, hata ayıkladığınız bir click handler'ın aslında üç farklı yerden tetiklendiğini işte böyle fark edersiniz.

debugger İfadesi ile Breakpoint Koyma

JavaScript'te kod akışını duraklatmanın en hızlı yolu tek bir kelime:

function computeTotal(items) {
    const subtotal = items.reduce((s, i) => s + i.price, 0);
    debugger;
    return subtotal * 1.08;
}

DevTools açıkken debugger; ifadesi tıpkı bir breakpoint gibi davranır — kod o satırda durur ve önünüze tam teşekküllü bir hata ayıklayıcı serilir: kapsamdaki değişkenler, çağrı yığını (call stack), step-over ve step-into kontrolleri, mevcut duruma göre ifade çalıştırma... hepsi elinizin altında. DevTools kapalıysa debugger; hiçbir şey yapmaz.

console.log yerine ilk kez gerçek bir debugger kullandığınızda, süper güç kazanmış gibi hissedersiniz. Önceden neyi yazdıracağınıza karar vermek zorunda kalmadan kapsamdaki her değişkeni görebilirsiniz. Koşullu ifadeler arasında adım adım ilerleyip hangi dalın çalıştığını izleyebilirsiniz. Canınızı sıkan bir bug'ı çözmek dakikalardan saniyelere iner.

Commit'lemeden önce debugger satırını silmeyi unutmayın — ya da daha da iyisi, Sources panelindeki satır numarasına tıklayarak doğrudan DevTools üzerinden breakpoint koyun.

Bilmeye Değer Chrome DevTools İpuçları

İnsanların yıllarca fark etmediği birkaç özellik var:

  • Koşullu breakpoint'ler: Sources panelinde bir satır numarasına sağ tıklayıp user.id === 42 gibi bir koşul tanımlayın. Breakpoint yalnızca koşul sağlandığında tetiklenir.
  • Logpoint'ler: Aynı menüdeki "Add logpoint" seçeneği. Kodunuzu hiç değiştirmeden ve çalışmayı durdurmadan mesaj yazdırır.
  • $_ konsolda: en son değerlendirilen ifadedir. Bir şey çalıştırın, sonra $_ ile sonucunu kapın.
  • $0: Elements panelinde o an seçili olan elemandır. $0.textContent ile tıkladığınız öğeyi inceleyebilirsiniz.
  • Nesneyi kopyala: Konsoldaki herhangi bir değere sağ tıklayıp "Store as global variable" deyin. Elinize temp1, temp2 gibi isimlerle kurcalayabileceğiniz değerler geçer.
  • Network paneli → Copy as fetch: Herhangi bir isteği, konsola yapıştırıp oynayabileceğiniz bir fetch() çağrısına çevirir.

Bunların hiçbiri olmazsa olmaz değil. Ama kas hafızanıza girdikten sonra her biri size bir sürü zaman kazandırır.

Ürüne Çıkmadan Önce Ortalığı Toparlayın

Geride kalan console.log çağrıları geliştirme sırasında zararsızdır ama production'da gürültü kirliliği yaratır. İşe yarayan birkaç alışkanlık:

  • Lint kuralı kullanın (ESLint'te no-console) ve başıboş log'ları yakalayın; warn ile error için istisna tanımlayın.
  • Ayrıntılı log'ları bir kontrolün içine sarın: if (process.env.NODE_ENV !== "production") console.log(...).
  • İz düzeyi çıktılar için console.debug tercih edin — çoğu bundler ve log toplayıcı bunu kolayca filtreleyebilir.
  • Daha da iyisi: küçük bir logger modülü (ya da debug gibi bir kütüphane) kullanın; böylece kodu elleyip durmadan log kategorilerini açıp kapatabilirsiniz.

Log almak bedava değil. Her çağrı argümanlarını serialize edip bir tampona yazar. Sıkı bir döngünün içinde unutulmuş bir log, performansı gözle görülür şekilde yavaşlatabilir.

Sıradaki Konu: Düzenli İfadeler (Regex)

İleride string işleyen kodları çokça debug edeceksiniz ve bu kodların önemli bir kısmı regex içerir — dilin en kompakt ve en kriptik özelliği. Bir sonraki bölüm, JavaScript'te düzenli ifadelere ve onları kullanan metotlara yumuşak bir girişle başlıyor.

Sıkça Sorulan Sorular

console.log ile console.dir arasındaki fark nedir?

console.log, değerleri tarayıcının varsayılan biçimlendirmesiyle yazdırır; bir DOM elementi verdiğinde onu HTML olarak render eder. console.dir ise her durumda JavaScript nesnesi görünümünü, yani özellik listesini gösterir. Bir elementin markup'ını değil özelliklerini incelemek istediğinde tam olarak ihtiyacın olan şey budur.

Chrome DevTools'ta console.log kullanmadan JavaScript nasıl debug edilir?

Sources panelini aç, dosyanı bul ve satır numarasına tıklayarak bir breakpoint koy. Kod o satıra geldiğinde duraklar; değişkenleri inceleyebilir, kodu adım adım çalıştırabilir ve console üzerinden ifadeler değerlendirebilirsin. Ayrıca koduna doğrudan debugger; ifadesi ekleyerek aynı breakpoint etkisini kaynak dosyadan da tetikleyebilirsin.

JavaScript kodunun çalışma süresini nasıl ölçerim?

Kodu aynı etikete sahip console.time('etiket') ve console.timeEnd('etiket') çağrıları arasına al. Console, geçen süreyi milisaniye cinsinden yazdırır. Daha detaylı bir profilleme için DevTools'taki Performance panelini kullanıp çalışan her şeyin flame chart kaydını alabilirsin.

console.table ne işe yarar?

console.table, dizileri ve nesneleri console içinde sıralanabilir bir tablo olarak gösterir; iç içe nesne çıktısından çok daha kolay okunur. Özellikle nesne dizileri için biçilmiş kaftan: her nesne bir satır, her anahtar bir sütun olur. İkinci argümanla sadece görmek istediğin sütunları da seçebilirsin.

Coddy ile kodlamayı öğren

BAŞLA