Görselleştirilmiş JavaScript: Hoisting
Bu yazı Lydia Hallie’nin JavaScript Visualized: Hoisting adlı makalesinin bir çevirisidir.
Hoisting, tüm JS geliştiricilerinin mutlaka duyduğu terimlerden biridir çünkü o can sıkıcı hatanızı Google’da aratmış, kendinizi Stack Overflow’da bulmuş ve biri size bu hatanın sebebinin hoisting olduğunu söylemiştir 🙃 Peki nedir bu hoisting? (Bu arada, scope konusu başka bir yazıda ele alınacak. Yazıları kısa ve odaklı tutmayı seviyorum.)
JavaScript’te yeniyseniz, bazı değişkenlerin rastgele undefined
tanımlanması, ReferenceError
verilmesi vs. gibi bazı “tuhaf” davranışlarla karşılaşmış olabilirsiniz. Hoisting genellikle değişkenleri ve fonksiyonları dosyanın en başına koymak olarak açıklanır ancak hayır, her ne kadar öyle gözükse de aslında bu doğru değil 😃
JS motoru, script’i aldığında yaptığı ilk şey kodumuzdaki veriler için bellek ayarlamaktır. Bu noktada hiçbir kod çalıştırılmaz, sadece çalışması için uygun ortam oluşturulur. Fonksiyon tanımlarının ve değişkenlerin bellekte tutulma şekilleri farklıdır. Fonksiyonlar, tüm fonksiyonun bir referansı ile depolanırlar.
Değişkenlerde durum biraz farklıdır. ES6, değişkenleri tanımlamak için iki yeni anahtar kelime sundu: let
ve const
. let
veya const
anahtar kelimeleri ile tanımlanan değişkenler initialized edilmeden (ilk değer verilmemiş/atanmamış olarak) depolanırlar.
var
anahtar kelimesi ile depolanan değişkenler undefined
varsayılan değeriyle depolanırlar.
Oluşturma aşaması bittiğine göre artık kodu çalıştırabiliriz. Dosyanın en başında fonksiyonu ya da herhangi bir değişkeni tanımlamadan önce 3 tane console.log ifademiz olsaydı ne olacağını görelim.
Fonksiyonlar, tüm fonksiyona bir referans ile depolandığı için onları oluşturduğumuz satırdan önce çağırabiliriz! 🔥
var
anahtar kelimesi ile tanımlanmış bir değişkeni, tanımlanmadan önce referans vermek istediğimizde depolandığı kendi varsayılan değerini döndürür: undefined
! Ancak, bu bazen “beklenmeyen” bazı davranışlara yol açabilir. Çoğu durumda bu, istemeden bir referansta bulunduğunuz anlamına gelir (muhtemelen undefined
değerine sahip olmasını istemezsiniz) 😬
var
anahtar kelimesinde olduğu gibi, undefined
bir değişkene yanlışlıkla referans vermeyi önlemek adına, ilk değeri atanmamış değişkenlere erişmek istediğimizde bir ReferenceError
verilir. Asıl tanımlanmaları öncesindeki “bölge”, geçici ölü bölge (temporal dead zone) olarak adlandırılır: ilk değerler verilmeden önce değişkenlere referans veremezsiniz (bu, ES6 classları için de geçerlidir!)
Motor, değişkenleri asıl tanımladığımız satırı geçtiğinde, bellekteki değerleri üzerine asıl değerleri yazılır.
(Bunun 7 numara olması gerektiğini şimdi fark ediyorum, en kısa sürede güncelleyeceğim 😬)
Hepsi tamam! 🎉 Hızlı bir özet:
- Fonksiyonlar ve değişkenler, kodumuzu çalıştırmadan önce execution context için bellekte depolanırlar. Buna hoisting denir.
- Fonksiyonlar tüm fonksiyonun referansıyla,
var
anahtar kelimesi ile tanımlanmış değişkenlerundefined
değeriyle,let
veconst
anahtar kelimeleri ile tanımlanmış değişkenleruninitialized
olarak depolanırlar.
Kodumuzu çalıştırdığımızda neler olduğunu gördüğümüze göre hoisting teriminin sizin için daha az karışık olduğunu umuyorum. Her zaman olduğu gibi eğer tüm bunlar pek bir anlam ifade etmiyorsa endişelenmeyin. Üzerlerinde çalıştıkça çok daha rahat edeceksiniz. Benim yardımımı istemekten de çekinmeyin, yardım etmeyi çok isterim! 😃