1. Null ve Undefined Değerlerini Karıştırmak
JavaScript’te en çok karıştırılan değerler arasında null ve undefined yer alır. Bu iki değer, görünüşte benzer olsa da, birbirinden tamamen farklıdır. Pek çok geliştirici, bu farkı göz ardı eder ve beklenmedik hatalarla karşılaşır. Peki, fark nedir?
- null: Bilerek "boş" bir değeri belirtir. Yani, değişkene herhangi bir değer atanmamıştır, ama ona null atanmıştır.
- undefined: Bir değişkenin değeri hiç atanmadığında, JavaScript otomatik olarak undefined değerini atar.
Örnek:
let a = null;
let b;
console.log(a); // null
console.log(b); // undefined
Null ve undefined arasındaki farkları bilmek, özellikle karşılaştırmalar yaparken size büyük kolaylık sağlar. Örneğin, null == undefined true döner, ancak null === undefined false döner. Bu küçük ama önemli fark, kodun doğru çalışmasını sağlar.
2. "this" Anahtar Kelimesinin Yanlış Kullanımı
JavaScript’teki en karmaşık konulardan biri "this" anahtar kelimesinin kullanımıdır. Çoğu zaman, özellikle arrow fonksiyonlar ile "this" kullanımında kafa karışıklığı yaşanır. Normal fonksiyonlar ve arrow fonksiyonlar arasında büyük farklar vardır.
- Normal Fonksiyonlar: "this", fonksiyonun çağrıldığı bağlama göre belirlenir.
- Arrow Fonksiyonlar: "this", fonksiyonun tanımlandığı bağlama göre belirlenir ve fonksiyon çalıştırıldığında değişmez.
Örnek:
function NormalFunc() {
this.value = 1;
setTimeout(function() {
this.value++;
console.log(this.value); // "this" burada farklı bir nesneyi işaret eder.
}, 1000);
}
const obj = new NormalFunc(); // Çalışırken beklenmedik bir değer dönebilir.
const ArrowFunc = () => {
this.value = 1;
setTimeout(() => {
this.value++;
console.log(this.value); // Arrow fonksiyonu olduğu için doğru bir şekilde 2 döner.
}, 1000);
}
const arrowObj = new ArrowFunc();
3. Kapanış (Closure) Hataları
Kapanışlar, JavaScript’in en güçlü özelliklerinden biridir. Ancak, kapanışlar üzerinde yanlış kullanımlar sıkça karşılaşılan hatalardandır. Bu, genellikle dışarıdaki fonksiyonun içindeki değişkenlerin erişimiyle ilgili karmaşıklıklardan kaynaklanır.
Örnek:
function outer() {
let count = 0;
return function inner() {
count++;
console.log(count);
}
}
const counter = outer();
counter(); // 1
counter(); // 2
Yukarıdaki örnekte, `inner()` fonksiyonu, dış fonksiyon olan `outer()`'ın `count` değişkenine erişebiliyor. Ancak, dışarıdan doğru şekilde erişilemiyor. Eğer doğru çalıştırmazsanız, `count` değeri sıfırlanabilir ve beklenmedik sonuçlar alabilirsiniz.
4. Asenkron Programlamadaki Yanlış Kullanımlar
Asenkron JavaScript kullanırken, özellikle Promise ve async/await yapıları arasındaki farkları iyi bilmek çok önemlidir. Hatalı Promise kullanımları veya `await`'in yanlış konumlandırılması, beklenmedik hatalara yol açabilir.
Örnek:
async function fetchData() {
let response = await fetch('https://api.example.com/data');
let data = await response.json();
console.log(data);
}
fetchData();
Burada, `await` ile asenkron bir işlemi bekliyoruz. Ancak, doğru kullanmazsanız, Promise'i doğru şekilde döndürmeyebilir ve callback hell adı verilen karmaşık yapılar ortaya çıkabilir.
5. Yavaş ve Verimsiz DOM Manipülasyonları
DOM manipülasyonları, web geliştirmede sıkça karşılaşılan bir işlemdir. Ancak, her DOM değişikliği doğrudan sayfanın yeniden render edilmesine yol açar. Bu da sayfanın performansını olumsuz etkileyebilir.
Örnek:
for (let i = 0; i < 1000; i++) {
const newElement = document.createElement('div');
newElement.textContent = `Element ${i}`;
document.body.appendChild(newElement); // Her eklemede DOM yeniden render edilir.
}
Yukarıdaki kod, her döngüde DOM'u tekrar render eder, bu da sayfanın yüklenmesini yavaşlatır. Bunun yerine, documentFragment kullanarak işlemi daha verimli hale getirebilirsiniz.
İpucu: DOM manipülasyonları yaparken, mümkünse birleştirme (batching) kullanın ve sayfa render'larını en aza indirin.
Sonuç
JavaScript, güçlü ve esnek bir dil olsa da, doğru kullanılmadığında kafa karıştırıcı olabilir. Ancak, yukarıda belirttiğimiz hatalardan kaçınarak çok daha verimli ve sorunsuz projeler geliştirebilirsiniz. Geliştirici olarak bu hataları fark ettiğinizde, sadece hatalarınızı düzeltmekle kalmaz, aynı zamanda daha sağlam bir yazılım geliştirme pratiği elde edersiniz. Unutmayın, her hata bir öğrenme fırsatıdır!