Closure = bir fonksiyonun, tanımlandığı kapsamdaki değişkenleri "hatırlama" yeteneği.
En basit örnek
function dis() {
let sayi = 0;
function ic() {
sayi++;
return sayi;
}
return ic;
}
const sayac = dis();
sayac(); // 1
sayac(); // 2
sayac(); // 3dis() fonksiyonu çalışıp bittikten sonra normalde sayi çöp toplayıcısı
tarafından silinmeliydi. Ama ic fonksiyonu hâlâ ona referans verdiği için
yaşamaya devam ediyor. İşte closure budur.
Pratik: özel sayaç
function sayacOlustur() {
let count = 0;
return {
arttir: () => ++count,
azalt: () => --count,
deger: () => count,
};
}
const s = sayacOlustur();
s.arttir(); // 1
s.arttir(); // 2
s.deger(); // 2
s.count; // undefined — dışarıdan erişilemezcount değişkeni private oldu. JavaScript'in eski sürümlerinde
encapsulation böyle yapılırdı.
Pratik: fonksiyon factory
function carpan(n) {
return (x) => x * n;
}
const ikiKati = carpan(2);
const onKati = carpan(10);
ikiKati(5); // 10
onKati(5); // 50carpan(2) çağrıldığında n=2 closure'da yakalanır.
Yaygın bug: döngüde var
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// Çıktı: 3, 3, 3 (!)var block scope olmadığı için tek bir i vardı, döngü bittiğinde 3
oldu. Tüm callback'ler aynı i'ye bakıyor.
let ile düzeltir:
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}
// Çıktı: 0, 1, 2 ✅let her tur için yeni bir binding oluşturur, her callback kendi i'sini
yakalar.
Closure, fonksiyonların kapsamlarını taşıyan olmasıdır. JavaScript'in async, callback ve fonksiyonel pattern'lerinin temelinde closure vardır.