JavaScript Closures

Daha önceki yazımda kapsam konusuna değinmiştim. Bu yazımda da onunla ilişkili olan closure (kapama) konusunu irdeleyeceğim.

Bir mülakatta closure nedir sorusuna şu cevap verilebilir. “Closure bir fonksiyonun, başka bir lexical scope tarafından çağırılsa bile kendi lexical scope’unu hatırlamasıdır.”

Başka bir değişle; bir fonksiyon kendi kapsamı dışındaki bir değişkeni kullanıyorsa ve bu fonksiyon başka bir kapsamdan çalıştırılsa bile o değişkene hala erişimi vardır.

Bu tanımı bilmeden bile muhtemelen yazdığınız kodlarda closure kullanmışsınızdır.

Aşağıdaki örneği düşünelim.

basla() fonksiyonu çağırıldıktan sonra ad değişkeninin GC tarafından toplanmasını bekleriz fakat closure buna izin vermez ve adiYazdir methodu tarafından hala erişilebilir durumda kalır.

Üstteki örnekte setTimeout() fonksiyonu ad değişkenine başla fonksiyonu çalıştıktan çok sonra closure sayesinde erişebilmektedir.

Bu durum iç içe geçmiş kapsamlarda da aynıdır.

Döngüler ve Closure

Üstteki örneği düşünecek olursak, sanki 1'er saniye aralıklarla 1,2,3,4,5 yazdıracakmış gibi duruyor. Fakat bu şekilde çalışmayacaktır. 6 sayısını 1'er saniye aralıklarla 5 defa yazdıracaktır. Bunun iki sebebi var. Yüzeysel ve derinlemesine sebepler.

Yüzeysel sebep, i değişkeni döngü tamamlandığında 6 değerine erişir ve console.log(i) her çağırıldığında artık 6 değerini taşır ve bunu yazdırır.

Derinlemesine soru şudur “Neden her iterasyonda yeni bir i oluşmaz?”. Çünkü var anahtar kelimesini kullanıyoruz. Kapsam ile ilgili yazdığım yazıda bahsetmeye çalışmıştım. İlgili kapsamda bir i değişkeni oluşur ve her bir iterasyonda setTimeout(i) methodu o i değişkenini kapatır.

Peki ya aşağıdaki gibi olsaydı.

İşte bu durumda IIFE kullanarak yazdığımız method artık döngüdeki i değişkenini değil de IIFE methoduna parametre olarak verilmiş i değişkenini kullanacağından beklediğimiz sonucu almış olacağız.

Let

Aynı sonucu elde etmenin bir yolu daha var o da sadece blok kapsamda geçerli olan değişkenler yaratmaya yarayan let anahtar kelimesi.

Bu durumda her bir iterasyon için yeni bir i değişkeni yaratmamıza let anahtar kelimesi yardımcı olur. Yani elimizde 5 farklı i değişkeni olur.

Closure javascriptte farkında olmadan kullandığımız yeteneklerden biri.