JavaScript Hoisting
10 Feb 2013Bu kitap basıma girdikten sonraki ilk yazım. Kitapta bu konudan bahsetmedim, belki sonraki baskılarda ekleme fırsatım olur.
JavaScript ilginç bir dil. Syntax yorumlanırken arkada bilmediğimiz, anlamadığımız, farketmediğimiz bir çok şey oluyor. Hoisting konusu da bunlardan birisi.
JavaScript’te scope bazlı hoisting yani yukarı kaldırma durumu sözkonusudur. Peki bu ne demek? Hemen kolayca başlayalım ve irdeleyelim:
Normal şartlar altında
değeri bize “ReferenceError: x is not defined” diye bir hata verir. Biz de bunun için doğal bir refleks olarak:
yazarız. Böylece ilk önce x’i tanımlar, sonra console’a veririz.
İşleri biraz değiştirelim.
yazarsak ne olacak? Aklımıza gelen ilk cevap şu: “Hata verir”. Çünkü bizce JavaScript var olmayan bir değişkeni önce basıp sonra tanımladı. – yanıldık.
JavaScript için bu kod şu şekilde yorumlandı:
x
değişkeni yukarı kaldırıldı ve bu sorun giderildi.
Neler Oluyor?
JavaScript identifier
verileri parse-time yani parse ederken düzenliyor. Bu sırada hoisting yapıyor.
Şimdi scope içerisinde bir örnek yapalım:
Bu kodun çıktısının (kodu gözümüzle takip ettiğimizde):
olmasını beklerken; çıktının
olduğunu görüyoruz.
Şimdi bunu hoisting ile açıklayalım; bu kod aslında hiç bir zaman bu şekilde yorumlanmadı. Parse-time’da kod şu şekilde algılandı:
Şimdi bu kodu gözümüzle takip ettiğimizde
sonucunu vermesini anormal karşılamayacağız. Çünkü var x;
scope içerisinde yukarı çekilerek x
değişkenini local hale getiriyor.
şeklinde yazsaydık, bu kez ilk beklediğimiz çıktıyı elde edecektik.
Biraz önceki örneği şimdi de bir fonksiyon için uygulayalım:
bu kod undefined
çıktısı verecektir. Fakat hata vermez. Çünkü aslında
şeklinde yorumlandı. Yani burada fonksiyon değil, var
keyword’ü yukarı çekildi. Bu noktada kafanın karışmaması önemli. Bu yüzden şimdi fonksiyonların yukarı çekilmesinden bahsedelim:
Fonksiyon Hoisting
var
keywordünün yukarı kaldırılması durumu aynı zamanda fonksiyonlar için de geçerli. Burada da çok ince bir çizgi olan
ile
arasındaki fark ortaya çıkıyor.
örneğini incelemiştik. Burada x
değeri undefined
olarak beliriyordu.
dediğimizde ise çıktının
olduğunu göreceğiz.
Dolayısıyla;
JavaScript parse edilirken yukarı çekildi;
bir fonksiyon deklarasyonu olarak değil, değişken deklarasyonu olarak yukarı çekildi. Yani değerinin ne olduğuna runtime
sırasında karar verilecek.
İlk kodumuz;
şeklinde yukarı çekilirken, diğer kodumuz;
şeklinde yukarı çekildi.
Gördüğünüz gibi, JavaScript yer yer farklı davranışlar sergileyebiliyor. Bu davranışları dikkate alarak davranmak ve kodumuzu buna göre yazmak gerekiyor.
Sonuç
Görüldüğü gibi, burada
ile
arasında ve aynı zamanda;
ile
arasında oldukça fark var. :)