[NODE JS] Closure Kavrami ve Pratik Kullanimi
Merhaba arkadaslar, bugun JavaScript'in en guclu ve en az anlasilmis kavramlarindan biri olan closure'lari inceleyecegiz. Closure, bir fonksiyonun disarida tanimlanmis degiskenlere erisebilme yetenegi ve bu degiskenleri hatirlama kapasitesidir. Bu kavram ilk basta soyut gorunebilir ama gercek hayatta surekli kullaniyoruz, cogu zaman farkinda bile olmadan.
Closure Nedir?
Closure, bir iç fonksiyonun dis fonksiyonun scope'undaki degiskenlere, dis fonksiyon calismasini bitirdikten sonra bile erisebilmesidir. JavaScript'te fonksiyonlar olusturuldukları ortamin referansini tasirlar. Yani bir fonksiyon nerede olusturulduysa, o anki degiskenleri hatirlar.
Bunu bir zarf gibi dusunun: bir fonksiyon olusturdugunuzda, cevresindeki degiskenleri bir zarfa koyup yaniinda tasiyor. Fonksiyon nereye giderse gitsin, zarfi acip o degiskenlere bakabiliyor. Bu guclu bir kavram cunku private degiskenler, factory fonksiyonlari ve memoization gibi pattern'leri mumkun kiliyor.
JavaScript:
// Temel closure ornegi
function sayacOlustur() {
let sayi = 0; // Bu degisken closure icinde yasar
return {
artir: function() {
sayi++;
return sayi;
},
azalt: function() {
sayi--;
return sayi;
},
degerAl: function() {
return sayi;
}
};
}
const sayac = sayacOlustur();
console.log(sayac.artir()); // 1
console.log(sayac.artir()); // 2
console.log(sayac.artir()); // 3
console.log(sayac.azalt()); // 2
console.log(sayac.degerAl()); // 2
// sayi degiskenine disaridan erisilemez!
// console.log(sayi); // ReferenceError!
// Her cagri yeni bir closure olusturur
const sayac2 = sayacOlustur();
console.log(sayac2.artir()); // 1 (bagimsiz!)
console.log(sayac.degerAl()); // 2 (etkilenmedi)
// Closure ile private degiskenler
function kullaniciOlustur(ad, sifre) {
// sifre degiskeni tamamen private
let _sifre = sifre;
let _girisDenemesi = 0;
return {
ad,
sifreDogrula: function(girdi) {
_girisDenemesi++;
if (_girisDenemesi > 3) {
return { basarili: false, mesaj: 'Cok fazla deneme, hesap kilitlendi' };
}
if (girdi === _sifre) {
_girisDenemesi = 0;
return { basarili: true, mesaj: 'Giris basarili' };
}
return { basarili: false, mesaj: `Yanlis sifre (Kalan: ${3 - _girisDenemesi})` };
},
sifreDegistir: function(eskiSifre, yeniSifre) {
if (eskiSifre !== _sifre) return false;
_sifre = yeniSifre;
return true;
}
};
}
const user = kullaniciOlustur('Ahmet', 'gizli123');
console.log('\n', user.sifreDogrula('yanlis'));
console.log(user.sifreDogrula('gizli123'));
// user._sifre erisilemez!
Pratik Kullanim Alanlari
Closure'larin gercek hayattaki en yaygin kullanim alanlari sunlar: fonksiyon factory'leri, memoization (onbellekleme), module pattern, partial application ve event handler'larda durum yonetimi. Bunlarin hepsini gunluk Node.js gelistirmesinde kullaniyorum.
JavaScript:
// 1. Factory fonksiyon
function loggerOlustur(onEk) {
let logSayisi = 0;
return function(mesaj) {
logSayisi++;
const zaman = new Date().toLocaleTimeString('tr-TR');
console.log(`[${zaman}] [${onEk}] #${logSayisi}: ${mesaj}`);
};
}
const apiLog = loggerOlustur('API');
const dbLog = loggerOlustur('DB');
apiLog('Istek alindi');
apiLog('Cevap gonderildi');
dbLog('Sorgu calistirildi');
// 2. Memoization (Onbellekleme)
function memoize(fn) {
const onbellek = new Map();
return function(...args) {
const anahtar = JSON.stringify(args);
if (onbellek.has(anahtar)) {
console.log(` [Cache HIT] ${anahtar}`);
return onbellek.get(anahtar);
}
console.log(` [Cache MISS] ${anahtar}`);
const sonuc = fn.apply(this, args);
onbellek.set(anahtar, sonuc);
return sonuc;
};
}
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
const hizliFib = memoize(fibonacci);
console.log('\n=== Memoization ===');
console.log('Sonuc:', hizliFib(10));
console.log('Sonuc:', hizliFib(10)); // Cache'den gelir
// 3. Rate limiter
function rateLimiter(limitSaniye, maxIstek) {
const istekler = [];
return function(islem) {
const simdi = Date.now();
const pencereBaslangic = simdi - (limitSaniye * 1000);
// Eski istekleri temizle
while (istekler.length > 0 && istekler[0] < pencereBaslangic) {
istekler.shift();
}
if (istekler.length >= maxIstek) {
return { izinVerildi: false, kalanSure: Math.ceil((istekler[0] + limitSaniye * 1000 - simdi) / 1000) };
}
istekler.push(simdi);
return { izinVerildi: true, kalanIstek: maxIstek - istekler.length };
};
}
const limiter = rateLimiter(60, 3); // 60 saniyede 3 istek
console.log('\n=== Rate Limiter ===');
console.log(limiter('istek1'));
console.log(limiter('istek2'));
console.log(limiter('istek3'));
console.log(limiter('istek4')); // Reddedilmeli
// 4. Partial Application
function createApiClient(baseUrl, defaultHeaders) {
return function(endpoint, options = {}) {
const url = baseUrl + endpoint;
const headers = { ...defaultHeaders, ...options.headers };
console.log(`\nAPI: ${options.method || 'GET'} ${url}`);
console.log('Headers:', headers);
return { url, headers, ...options };
};
}
const api = createApiClient('https://api.example.com', {
'Authorization': 'Bearer token123',
'Content-Type': 'application/json'
});
api('/users');
api('/posts', { method: 'POST' });
Closure Tuzaklari
Closure kullaniurken en sik dusülen tuzak, dongulerde closure olusturmaktir. var ile tanimlanan degiskenler fonksiyon scope'ludur, block scope'lu degildir. Bu yuzden bir dongu icinde closure olusturdugunuzda, tum closure'lar ayni degiskeni paylasiyor olur. Cozum: let kullanmak (block scope) veya IIFE (Immediately Invoked Function Expression) kullanmak.
Diger tuzak memory leak. Closure'lar referans tuttugu degiskenlerin garbage collect edilmesini engeller. Buyuk nesnelere referans tutan closure'lar bellekte kalir ve zamanla sorun yaratabilir. Benim tecrubeme gore, closure icinde sadece ihtiyaciniz olan degiskenleri referans alin ve gereksiz buyuk nesnelerden kacinin. Bu kadar, bu konuyu da bitirdik. Simdi HTTP dunyasina giriyoruz!
Emeğiniz ve katkınız için teşekkür ederiz!
Konunuz gerekli incelemelerden geçerek onaylandı. Topluluğumuza katkılarınızın devamını bekliyoruz.
İyi forumlar!
Konunuz gerekli incelemelerden geçerek onaylandı. Topluluğumuza katkılarınızın devamını bekliyoruz.
İyi forumlar!

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)
Benzer konular
- Cevaplar
- 2
- Görüntüleme
- 380
- Cevaplar
- 9
- Görüntüleme
- 229
- Kilitli
- Cevaplar
- 7
- Görüntüleme
- 2K
- Kilitli
- Cevaplar
- 1
- Görüntüleme
- 432
- Cevaplar
- 3
- Görüntüleme
- 283