JavaScript Hoisting Nedir ?
Hoisting, JavaScript ile geliştirme yapıyorsanız çokça karşılaşacağınız bir kavramdır. Yeterince bilinmediği durumlarda, uygulamanızda ciddi sorunlara neden olabilir. Bu yazıda, JavaScript’te Hoisting nedir ? Ne için var ? gibi sorulara cevap vermeye çalışacağım; keyifli okumalar…
Hoisting Nedir ? Tanımlama
JavaScript’te Hoisting kısaca kodda bir değişkenin veya fonksiyonun ne zaman tanımlandığının değiştirilmesi olayıdır.
Kelime anlamı “yukarı çekmek, kaldırmak” olan Hoisting, kodda tanımlanan bazı değişken ve-ya fonksiyon’ların yorumlayıcının en üst seviyesine taşınmasıdır.
Neden Hoisting Var ?
Normal bir JavaScript uygulamasında, kodlar ilk satırdan başlayarak sırasıyla aşağıya doğru devam ederek çalıştırılır. Ancak, Hoisting sayesinde kodda tanımlanan bazı değişken ve-ya fonksiyonlar; tanımlandıkları yere bakılmaksızın, kodun en üst seviyesine taşınır ve memory’de tutulur. Bu sayede bu değeler kodda her yerde erişilebilir hale gelir. Bu durumun temel amacı JavaScript’in karmaşık kodları çalıştırmasını ve derlemesini kolaylaştırmaktır. Yani Hoisting, JavaScript’in bazı değişken ve fonksiyonlara erişmek için kodda gezinmesine gerek kalmadan önceden en üstte tanımlamasıdır.
Değişkenlerde Hoisting
Değişkenlerde Hoisting olayı yalnızca var
keyword’ü ile yapılan tanımlamalarda meydana gelir. Yani let
ve const
ile yapılan değişken tanımlamalarında Hoisting olayı meydana gelmez.
// true
var cod = "erdal";
// false
const cod = "erdal";
let cod = "erdal";
Hatta bu durum, var
keyword’ü ile yapılan değişken tanımlamalarının bazılarının global scope’a taşınmasının temel nedenidir. Değişken programın en üst noktasına taşındığı için; programın her yerinde erişilebilir hale gelir.
Ancak burada dikkat edilmesi gereken önemli bir nokta var, değişkenlerde Hoisting olayı yalnızca tanımlamaların hoist edilmesini (üste taşınmasını) sağlar, değişkenin değerini üste taşımaz. JavaScript yalnızca bu değişkenin tanımlandığı bilgisine sahip olur. Yani var
keyword’ü ile tanımladığınız değişkenleri tanımlama bloğundan önce kullanmaya çalışırsanız undefined
değerini alırsınız. Bu da bildiğiniz üzere, değişkenin tanımlandığını ancak henüz bir değer atanmadığını temsil eder.
Ancak let
ve const
ile tanımlanan değişkenleri, tanımlamadan önceden kullanmaya çalışırsanız, Hoisting olayı olmayacağından, referans hatası alırsınız.
console.log(erdal);// undefined
// hoist | non-hoist
var erdal = "coderdal";
console.log(erdal);// coderdal
console.log(erdal);// ReferenceError
// no hoisting
const erdal = "coderdal";
let erdal = "coderdal";
console.log(erdal);// coderdal
Fonksiyonlarda Hoisting
Fonksiyonlarda ise, hem fonksiyonun kendisi hem de işlevi Hoisting olayına maruz kalır. Ancak fonksiyonlarda Hoisting olayı yalnızca named function’larda meydana gelir. Function expression’larda Hoisting yapılmaz. Yani sadece function
keyword’ü ile yapılan named function tanımlamalarında Hoisting meydana gelir.
// true
function sayHello() {
console.log("Hello from named function.");
}
// false
const sayHi = () => console.log("Hi from function expression.");
var sayHi = () => console.log("Hi from function expression.");
let sayHi = () => console.log("Hi from function expression.");
const sayHi = function() {console.log("Hi from function expression.")};
var sayHi = function() {console.log("Hi from function expression.")};
let sayHi = function() {console.log("Hi from function expression.")};
(var = Function) !== Hoisting
var
keyword’ü ile tanımladığımız fonksiyonun işlevinin olmamasının nedeni, Değişkenlerde Hoisting olayının sadece değişkenin tanımlamasına yapılmasıdır. Yani değişkenin değeri tanımlanana kadar undefined
olarak kalır, bu nedenle var ile tanımlanan fonksiyonda Hoisting olayı olmaz.
Günün sonunda sağdaki kutucukta bulunan kodlar çalıştığında, memory’de başlangıç değerleri soldaki tabloda olduğu gibi olacaktır.