Görselleştirilmiş JavaScript: Hoisting

Gizem Korkmaz
3 min readMay 5, 2022

--

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.

1 || 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.

2 || let veya const anahtar kelimeleri ile tanımlanan değişkenler initialized edilmeden (ilk değer verilmemiş/atanmamış olarak) depolanırlar (ES6 classları da buna dahildir).

var anahtar kelimesi ile depolanan değişkenler undefined varsayılan değeriyle depolanırlar.

3 || 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! 🔥

4 || Kodun çalıştırılma aşamasında, fonksiyonları onları tanımlamadan önce çağırabiliriz çünkü fonksiyonun bir referansı bellekte mevcut.

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) 😬

5 || var anahtar kelimesi ile tanımladığımız bir değişkene tanımlanmadan önce referans verdiğimizde değeri varsayılan değeri olan undefined olur

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!)

6 || İlk değerleri atanmamış değişkenlere erişmek istediğimizde bir ReferenceError verilir. Buna geçici ölü bölge denir.

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 😬)

6 || Değişkenleri tanımladığımız satırı geçtiğimiz an bellekteki değerler güncellenir.

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şkenler undefined değeriyle, let ve const anahtar kelimeleri ile tanımlanmış değişkenler uninitialized 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! 😃

--

--