Closure’lar
Kapsamı (scope) zaten biliyorsunuz: buradan hangi adlar görünür. Bir adım ötesi: dış çağrı bittikten sonra bile iç fonksiyon dış bir adı kullanmaya devam edebilir. Bu kalıcı bağ closure’dır.
Closure ne demek
Bir fonksiyon başka birinin içinde oluşur ve sonra hâlâ dış fonksiyonun bağlamalarına ulaşırsa closure oluşur. Dış çağrı bitmiş olabilir; iç fonksiyon o adları yine «anımsar». Kodda closure kelimesini yazmazsınız — iç içe fonksiyonlar yazarsınız, JavaScript gereken dış bağlamaları canlı tutar.
İzlenecek üç parça
📊 Dış fonksiyon, bağlama ve iç fonksiyon
| Parça | Rol | Yeni başlayan ipucu |
|---|---|---|
| dış fonksiyon | bir (veya daha çok) kez çalışır, çoğu zaman iç fonksiyon döndürür | «kurulum» çağrısı |
| dış bağlama | dıştaki parametre veya let / const |
için hâlâ ihtiyaç duyduğu değer |
| iç fonksiyon | sonra çağırdığınızda o bağlamayı kullanır | sakladığınız fonksiyon |
Bu üçü gösterebilirseniz, neredeyse her başlangıç closure örneğini açıklarsınız. Sürpriz iç içelik değil — dış return’den sonra dış bağlamanın hâlâ işe yaramasıdır.
function makeLine(title) {
function show() {
console.log(title);
}
show();
}
makeLine("Shop");
Çağrı sırasında iç dışa bakar
show’un yerel title’ı yok. Arama dışa makeLine’a yürür ve parametreyi bulur. Bu sıradan iç içe kapsamdır. Closure bir adım öteye gider: makeLine döndükten sonrası için show’u (veya ikizini) saklayın.
function makeLine(title) {
return function show() {
console.log(title);
};
}
let printShop = makeLine("Shop");
printShop();
Dış çağrı bitti — bellek kaldı
makeLine("Shop") bir fonksiyon döndürür. Sonra printShop’u çağırdığınızda hâlâ Shop yazdırır. O bitmiş çağrıdaki title parametresi hâlâ erişilebilir. Bu kalıcı yakalama closure’dır.
function makeGreeter(name) {
return function () {
return "Hello, " + name;
};
}
let hiSara = makeGreeter("Sara");
console.log(hiSara());
Fabrikalar hazır fonksiyon döndürür
makeGreeter küçük bir fabrikadır: bir dış çağrı, özelleşmiş bir fonksiyon geri. hiSara her zaman Sara’yı selamlar çünkü o name üzerine kapanmıştır. makeGreeter argümanını değiştirin, başka bir selamlayıcı alın — aynı kalıp, yeni bellek.
function makeCounter() {
let n = 0;
return function () {
n = n + 1;
return n;
};
}
let tick = makeCounter();
console.log(tick());
console.log(tick());
Sayaçla neredeyse özel durum
n dış fonksiyonda yaşar. Dış kod n’e doğrudan dokunmaz — yalnızca dönen fonksiyon dokunabilir. İlk çağrı 1, ikinci 2 döner. Sayaç global değişken olmadan «anımsar».
function makeCounter() {
let n = 0;
return function () {
n = n + 1;
return n;
};
}
let a = makeCounter();
let b = makeCounter();
console.log(a());
console.log(a());
console.log(b());
Her dış çağrının kendi belleği vardır
a ve b ayrı makeCounter() çağrılarından geldi, bu yüzden her birinin kendi n’i var. a üzerinde iki adım b’yi ortadan başlatmaz. Closure’lar bilerek bir dış bağlamayı paylaşmadıkça otomatik ortak durum torbası paylaşmaz.
Kapanmış değeri sayfada gösterin
Fabrikayla bir selamlayıcı kurun, bir kez çağırın, dönen dizgeyi paragrafa yazın.
<!DOCTYPE html>
<html>
<head>
<title>closures — page</title>
</head>
<body>
<p id="msg">…</p>
<script>
function makeGreeter(name) {
return function () {
return "Hello, " + name;
};
}
let hi = makeGreeter("Omar");
let box = document.getElementById("msg");
box.textContent = hi();
</script>
</body>
</html>
Paragraf Hello, Omar gösterir. Dış çağrı bitti; hi hâlâ name’i bilir. Yalnızca makeGreeter’a verilen dizgeyi değiştirin, yenileyin, yeni satırı okuyun. Sırada: nesneler (objects) — ilgili değerler tek ad altında.
Alıştırmalar
- Dış parametreyi loglayan bir iç fonksiyon döndüren fonksiyon yazın.
- Dönen fonksiyonu değişkende saklayıp dış çağrı bittikten sonra çağırın.
makeGreeter("Lina")kurun ve döndürdüğü dizgeyi loglayın.- Bir sayaç oluşturun; iki kez çağırıp önce
1sonra2görün. - İki sayaç oluşturun; yalnızca birincisini iki kez artırın, ikincinin
1’den başladığını kontrol edin. - HTML demoda yalnızca ad argümanını değiştirin, yenileyin, paragrafı okuyun.
Sık yanlışlar
- Dış yerellerin
returnanında yok olduğunu sanmak — iç hâlâ görebilir - Her
makeCounter()’ın teknpaylaşmasını beklemek — genelde her çağrının kendi belleği vardır - «Closure»ün yalnızca
returnkelimesi olduğunu düşünmek —returniçi verebilir, bellek kapanmış bağlamadır - Anımsanacak her değeri global nesneye koymak «basitlik için»
- Burada tam nesne dersi beklemek — özellikleri tek değer altında toplamak sonraki sayfa
Özet
- Closure, iç fonksiyonun dış çağrı bittikten sonra da dış adları kullanmasına izin verir
- İç içe fonksiyon yazarsınız; JavaScript gereken bağlamaları canlı tutar
- Fabrikalar kurulum değerlerini anımsayan özelleşmiş fonksiyon döndürür
- Sayaçlar özel
n’i dönen fonksiyonun arkasında gizler - Ayrı dış çağrılar genelde ayrı bellek demektir
- Sayfa güncellemesi kapanmış addan üretilmiş dizge gösterebilir
- Sırada: nesneler — ilgili değerler tek ad altında
🧠 Bilginizi Test Edin
Bilginizi Test Edin
Bu interaktif sınavla kendini test et ve konuyu ne kadar iyi anladığını gör
📝 Talimatlar
- Her soruyu dikkatle okuyun
- Her soru için en iyi cevabı seçin
- Quiz'i istediğiniz kadar tekrar alabilirsiniz
- İlerlemeniz üstte gösterilecek