hoisting ne demek?

Hoisting (Yukarı Taşıma)

Hoisting, JavaScript ve bazı diğer programlama dillerinde, değişken ve fonksiyon tanımlamalarının kodun en başına "taşınmış" gibi davranılması durumunu ifade eden bir kavramdır. Bu "taşıma" işlemi fiziksel bir kod değişikliği olmasa da, derleyici veya yorumlayıcı tarafından kodun yürütülme aşamasında farklı bir şekilde ele alınmasına yol açar. Bu davranış, özellikle JavaScript'e yeni başlayan geliştiriciler için kafa karıştırıcı olabilir ve beklenmedik hatalara neden olabilir.

Temel İlkeler

Hoisting'in temelinde yatan fikir, JavaScript motorunun kodu iki aşamada işlemesidir:

  1. Derleme (Compilation) Aşaması: Bu aşamada, motor kodu tarar, değişken ve fonksiyon tanımlamalarını belirler ve bunları bir "sözlük" oluşturarak kaydeder. Hoisting, işte bu aşamada gerçekleşir. Tanımlamalar, kodun en üstüne "taşınır".
  2. Yürütme (Execution) Aşaması: Bu aşamada, kod satır satır çalıştırılır. Daha önce "taşınmış" olan değişken ve fonksiyon tanımlamaları, yürütme sırasında kullanılabilir hale gelir.

Önemli Not: Hoisting, yalnızca tanımlamaları taşır, atamaları değil. Bu, değişkenin değeri atama yapılana kadar undefined kalacağı anlamına gelir.

Değişken Hoisting'i

JavaScript'te değişken tanımlamaları var, let ve const anahtar kelimeleri ile yapılır. Ancak, bu üçünün hoisting davranışı birbirinden farklıdır:

  • var: var ile tanımlanan değişkenler hoisted edilir ve varsayılan olarak undefined değeri atanır. Bu, değişken tanımlandığı satırdan önce kullanılabilir demektir, ancak değeri undefined olacaktır.

    console.log(x); // undefined
    var x = 10;
    console.log(x); // 10
    

    Yukarıdaki örnekte, x değişkeni tanımlanmadan önce kullanılmasına rağmen hata alınmaz, çünkü var ile tanımlanan değişkenler hoisted edilir ve undefined değeri ile başlatılır.

  • let ve const: let ve const ile tanımlanan değişkenler de hoisted edilir, ancak var'dan farklı olarak, henüz başlatılmamış bir durumda kalırlar. Bu duruma "Temporal Dead Zone" (TDZ) denir. TDZ, değişken tanımlandığı satıra gelene kadar değişkene erişmeyi engeller ve bu durumda hata oluşur.

    console.log(y); // ReferenceError: Cannot access 'y' before initialization
    let y = 20;
    console.log(y); // 20
    
    console.log(z); // ReferenceError: Cannot access 'z' before initialization
    const z = 30;
    console.log(z); // 30
    

    let ve const ile tanımlanan değişkenlerin TDZ'de olması, daha güvenli bir kod yazılmasını sağlar, çünkü değişkenin beklenmedik bir şekilde undefined değerinde kullanılmasını engeller.

Fonksiyon Hoisting'i

JavaScript'te fonksiyonlar iki şekilde tanımlanabilir:

  • Fonksiyon Bildirimi (Function Declaration): Bu şekilde tanımlanan fonksiyonlar tamamen hoisted edilir, yani fonksiyonun hem adı hem de içeriği kodun en üstüne taşınır. Bu, fonksiyonun tanımlandığı satırdan önce çağrılabileceği anlamına gelir.

    greet(); // "Merhaba!"
    function greet() {
      console.log("Merhaba!");
    }
    
  • Fonksiyon İfadesi (Function Expression): Bu şekilde tanımlanan fonksiyonlar, değişken hoisting'ine benzer şekilde davranır. Fonksiyon ifadesi var ile tanımlanmışsa, değişken hoisted edilir ve undefined değeri atanır. Fonksiyon ifadesi let veya const ile tanımlanmışsa, değişken TDZ'de kalır ve tanımlandığı satıra gelene kadar kullanılamaz.

    console.log(sayHello); // undefined
    var sayHello = function() {
      console.log("Merhaba!");
    };
    sayHello(); // "Merhaba!"
    
    console.log(sayGoodbye); // ReferenceError: Cannot access 'sayGoodbye' before initialization
    let sayGoodbye = function() {
      console.log("Güle güle!");
    };
    sayGoodbye(); // "Güle güle!"
    

Neden Hoisting Var?

Hoisting'in varlığı, JavaScript'in tasarımının bir sonucudur. Temel olarak, karşılıklı olarak birbirini çağıran fonksiyonlar gibi bazı programlama örüntülerini desteklemek amacıyla ortaya çıkmıştır.

Hoisting'in Potansiyel Sorunları

Hoisting, özellikle JavaScript'e yeni başlayan geliştiriciler için kafa karıştırıcı olabilir ve aşağıdaki gibi sorunlara yol açabilir:

  • Beklenmedik undefined Değerleri: var ile tanımlanan değişkenlerin hoisted edilmesi ve undefined değeri ile başlatılması, değişkenin tanımlandığı satırdan önce kullanılması durumunda beklenmedik sonuçlara yol açabilir.
  • ReferenceError Hataları: let ve const ile tanımlanan değişkenlerin TDZ'de olması, değişkenin tanımlandığı satırdan önce kullanılması durumunda ReferenceError hatasına neden olur.
  • Okunabilirlik Sorunları: Hoisting, kodun okunabilirliğini azaltabilir, çünkü değişken ve fonksiyon tanımlamalarının nerede yapıldığını takip etmek zorlaşır.

Hoisting'den Kaçınma ve İyi Uygulamalar

Hoisting'den kaynaklanan sorunları önlemek için aşağıdaki iyi uygulamalara dikkat etmek önemlidir:

  • Değişkenleri ve Fonksiyonları Kullanmadan Önce Tanımlayın: En iyi uygulama, değişkenleri ve fonksiyonları kullanmadan önce tanımlamaktır. Bu, kodun okunabilirliğini artırır ve hoisting'den kaynaklanan sorunları önler.
  • let ve const Kullanın: var yerine let ve const kullanmak, değişkenlerin TDZ'de kalmasını sağlayarak daha güvenli bir kod yazılmasını sağlar.
  • Fonksiyon Bildirimlerini Tercih Edin: Mümkünse fonksiyon ifadeleri yerine fonksiyon bildirimlerini kullanın. Fonksiyon bildirimleri tamamen hoisted edilir, bu da fonksiyonun tanımlandığı satırdan önce çağrılabileceği anlamına gelir.
  • "Strict Mode" Kullanın: JavaScript'te "strict mode" kullanmak, bazı hoisting ile ilgili davranışları değiştirerek hataları daha erken tespit etmeye yardımcı olur.

Sonuç

Hoisting, JavaScript'in kendine özgü bir özelliğidir. Nasıl çalıştığını anlamak, daha güvenli ve okunabilir kod yazmanıza yardımcı olacaktır. İyi uygulamalara dikkat ederek ve let ile const gibi modern JavaScript özelliklerini kullanarak, hoisting'den kaynaklanan sorunları en aza indirebilirsiniz. JavaScript Motoru da bu konuda önemli rol oynar.

Kendi sorunu sor