Takip et

JavaScript Değişkenleri Neden Bu Kadar Önemli?


JavaScript Değişkenler: Programlamanın Temel Taşı

JavaScript değişkenleri, modern web uygulamalarının ve programlama mantığının temel yapı taşlarından biridir. Kodunuzda geçici veya kalıcı olarak bilgi depolamanın ve bu bilgilere erişmenin anahtar mekanizmasıdır. Bu kapsamlı rehberde, var, let, const gibi değişken tanımlama yöntemleri arasındaki kritik farkları, kullanım alanlarını ve en iyi uygulamaları derinlemesine inceleyeceğiz. Böylece, programlama serüveninize sağlam bir başlangıç yapacak ve JavaScript’in veri yönetimi yeteneklerini tam anlamıyla kavrayacaksınız.

Programlama dünyasına adım atan herkesin ilk öğrendiği kavramlardan biri değişkenlerdir. Peki, bu değişkenler neden bu kadar büyük bir öneme sahiptir ve herhangi bir programlama dilinde, özellikle de JavaScript’te, neden vazgeçilmez bir role sahiptirler? En basit ifadeyle, değişkenler, bilgisayar belleğinde geçici olarak veri depolamak için kullanılan isimlendirilmiş depolama alanlarıdır. Tıpkı bir kutunun içine eşyalarınızı koyup üzerine bir etiket yapıştırdığınız gibi, değişkenler de bilgileri saklamamızı ve bu bilgilere bir isim aracılığıyla kolayca erişmemizi sağlar. Bu sayede, programınızın farklı noktalarında aynı verilere başvurabilir, onları değiştirebilir ve manipüle edebilirsiniz.

Bir web uygulamasında kullanıcı adı, alışveriş sepetindeki ürün sayısı, bir butonun tıklanma durumu veya anlık döviz kuru gibi yüzlerce farklı türde veriyi yönetmeniz gerekebilir. İşte tam bu noktada, değişkenler devreye girer. Bu verileri her seferinde baştan yazmak yerine, bir değişkene atayarak programınızın daha düzenli, okunabilir ve yönetilebilir olmasını sağlarsınız. Örneğin, bir kullanıcının sepetine ürün eklediğinde, sepetUrunSayisi adında bir değişkenin değerini artırmak, kodun ne yaptığını çok daha net bir şekilde ortaya koyar. Ayrıca, eğer sepetin maksimum ürün kapasitesi gibi bir sabit değer varsa, bunu MAX_SEPET_KAPASITESI gibi bir değişkende saklamak, programın bakımını ve gelecekteki değişiklikleri kolaylaştırır.

Değişkenler olmadan, kodunuz karmaşık, tekrarlayan ve hatalara açık hale gelir. Herhangi bir veri değişikliği gerektiğinde, bu verinin geçtiği tüm satırları tek tek bulup güncellemeniz gerekir ki bu, büyük projelerde neredeyse imkansızdır. Dolayısıyla, değişkenler sadece veri depolamakla kalmaz, aynı zamanda kodun modülerliğini, esnekliğini ve yeniden kullanılabilirliğini artırarak modern yazılım geliştirmenin temelini oluşturur. JavaScript’in dinamik yapısı sayesinde, değişkenler farklı türlerdeki verileri (sayılar, metinler, boolean değerler, nesneler vb.) kolayca saklayabilir ve hatta çalışma zamanında tiplerini değiştirebilir. Bu esneklik, geliştiricilere büyük bir güç verirken, aynı zamanda değişkenlerin doğru ve dikkatli bir şekilde yönetilmesini de zorunlu kılar. Bu yüzden, değişkenlerin nasıl tanımlandığını, nasıl çalıştığını ve aralarındaki farkları anlamak, etkili JavaScript kodu yazmanın ilk ve en önemli adımıdır.

JavaScript’te Değişken Tanımlama: Var, Let ve Const Arasındaki Farklar Nelerdir?

JavaScript’te değişken tanımlamak için üç ana anahtar kelime bulunur: var, let ve const. Tarihsel olarak var en eski yöntemdir ve JavaScript’in ilk zamanlarından beri kullanılmaktadır. Ancak ES6 (ECMAScript 2015) ile birlikte hayatımıza giren let ve const, değişken yönetimi konusunda çok daha modern ve güvenli yaklaşımlar sunmuştur. Bu üç anahtar kelimenin her birinin kendine has özellikleri, kapsama alanları (scope) ve kullanım senaryoları vardır. Bu farkları anlamak, temiz, hatasız ve bakımı kolay JavaScript kodu yazmak için kritik öneme sahiptir.

var Anahtar Kelimesi: Geleneksel Yaklaşım

var ile tanımlanan değişkenler, JavaScript’in en eski ve en esnek değişken tanımlama yöntemidir. Temel özelliği ‘function scope’a sahip olmasıdır. Yani, bir fonksiyon içinde tanımlanan var değişkeni yalnızca o fonksiyon içinde erişilebilirken, fonksiyon dışında tanımlanan bir var değişkeni global scope’ta bulunur ve her yerden erişilebilir. En önemli davranışlarından biri de ‘hoisting’dir. var ile tanımlanan bir değişken, içinde bulunduğu scope’un en üstüne taşınır, ancak sadece bildirimi (declaration) taşınır, ataması (initialization) değil. Bu durum, beklenmedik davranışlara ve hatalara yol açabilir. Örneğin:


  console.log(mesaj); // undefined (hoisting nedeniyle bildirim yukarı taşınır)
  var mesaj = "Merhaba dünya!";
  console.log(mesaj); // Merhaba dünya!

  function ornekFonksiyon() {
    var sayi = 10;
    if (true) {
      var sayi = 20; // Aynı değişken yeniden tanımlanabilir!
      console.log(sayi); // 20
    }
    console.log(sayi); // 20 (var block scope'a sahip değil)
  }
  ornekFonksiyon();
  // console.log(sayi); // Hata: sayi is not defined (function scope)

Yukarıdaki örnekte görebileceğiniz gibi, var ile aynı isimde bir değişkeni birden fazla kez tanımlamak mümkündür ve bu durum genellikle kodun karmaşıklığını ve hata potansiyelini artırır. Ayrıca, if bloğu içinde tanımlanan sayi değişkeninin if bloğu dışından da erişilebilir olması (function scope nedeniyle), çoğu zaman istenmeyen bir durumdur ve 'shadowing' gibi hatalara yol açabilir.

let Anahtar Kelimesi: Esnek ve Güvenli Seçim

let anahtar kelimesi, ES6 ile birlikte gelmiş ve var'ın birçok dezavantajını gidermiştir. En belirgin özelliği 'block scope'a sahip olmasıdır. Bu, let ile tanımlanan bir değişkenin yalnızca tanımlandığı blok (süslü parantezler {}) veya alt bloklar içinde erişilebilir olduğu anlamına gelir. let değişkenleri yeniden tanımlanamaz, ancak değerleri sonradan değiştirilebilir. let de hoisting'e tabidir, ancak 'Temporal Dead Zone (TDZ)' adı verilen bir mekanizma nedeniyle, değişken tanımlanmadan önce erişilmeye çalışılırsa bir hata fırlatır. Bu, var'daki undefined sorununu çözerek daha güvenli bir davranış sunar.


  // console.log(isim); // Hata: Cannot access 'isim' before initialization (TDZ)
  let isim = "Ahmet";
  console.log(isim); // Ahmet

  function ornekFonksiyonLet() {
    let yas = 30;
    if (true) {
      let yas = 40; // Farklı bir değişken, yeni bir block scope'ta
      console.log(yas); // 40
    }
    console.log(yas); // 30 (Dış bloktaki yas değişkeni hala geçerli)
  }
  ornekFonksiyonLet();

  let renk = "mavi";
  // let renk = "kırmızı"; // Hata: 'renk' zaten tanımlanmış
  renk = "yeşil"; // Değeri değiştirilebilir
  console.log(renk); // yeşil

let sayesinde, değişkenlerin kapsamını daha iyi kontrol edebilir ve aynı isme sahip değişkenlerin farklı bloklarda bağımsız olarak çalışmasını sağlayabiliriz. Bu, özellikle döngüler ve koşullu ifadeler içinde değişken yönetimi yaparken kodun okunabilirliğini ve güvenilirliğini önemli ölçüde artırır.

const Anahtar Kelimesi: Sabit Değerler İçin

const da let gibi ES6 ile gelmiş olup, let ile benzer şekilde 'block scope' ve 'Temporal Dead Zone (TDZ)' özelliklerine sahiptir. Ancak const'un temel farkı, bir kez tanımlandıktan sonra değerinin değiştirilemez olmasıdır. Bu yüzden const ile bir değişken tanımladığınızda, ona hemen bir başlangıç değeri atamanız zorunludur. Genellikle sabit kalması beklenen değerler (örneğin, bir API anahtarı, maksimum deneme sayısı, PI sayısı) için kullanılır.


  const PI = 3.14159;
  // PI = 3.14; // Hata: Assignment to constant variable.

  const KULLANICI_ADI = "admin";
  // const KULLANICI_ADI; // Hata: Missing initializer in const declaration

  function ornekFonksiyonConst() {
    const ID = 123;
    if (true) {
      const ID = 456; // Yeni bir block scope'ta farklı bir ID
      console.log(ID); // 456
    }
    console.log(ID); // 123
  }
  ornekFonksiyonConst();

Dikkat edilmesi gereken önemli bir nokta, const'un değişkenin kendisinin referansını sabitlemesidir, değerini değil (ilkel tipler için değerini de sabitler). Eğer bir const değişkenine bir nesne veya dizi atanırsa, bu nesne veya dizinin özelliklerini veya elemanlarını değiştirmek mümkündür. const sadece o değişkenin başka bir nesneye/diziye yeniden atanamayacağını garanti eder.


  const ayarlar = { tema: "dark", dil: "tr" };
  ayarlar.tema = "light"; // Bu geçerlidir! Nesnenin içeriği değişebilir.
  console.log(ayarlar); // { tema: "light", dil: "tr" }

  // ayarlar = { tema: "light", dil: "en" }; // Hata: Assignment to constant variable.

Vaka Analizi: Neden let ve const tercih edilmeli?
Modern JavaScript geliştirme pratiklerinde, var kullanımı genellikle tavsiye edilmez. var'ın esnekliği (yeniden tanımlanabilme, function scope) çoğu zaman istenmeyen yan etkilere ve hatalara yol açabilir, özellikle büyük kod tabanlarında veya takım çalışmalarında. Örneğin, bir döngü içinde var ile tanımlanan bir değişken, döngü dışından da erişilebilir hale gelir ve döngü tamamlandıktan sonra bile son değerini korur. Bu, özellikle asenkron işlemlerde (callbacks, Promises) beklenmedik sonuçlara yol açabilir.

Bunun yerine, geliştiricilere genellikle şu kurala uymaları tavsiye edilir: eğer bir değişkenin değeri asla değişmeyecekse const kullanın. Eğer değişkenin değeri daha sonra değişecekse (örneğin, bir sayaç, bir form alanı değeri), let kullanın. Bu yaklaşım, kodun niyetini açıkça belirtir ve potansiyel hataları azaltır. const kullanmak, kodun daha güvenli ve öngörülebilir olmasını sağlar, çünkü bir değerin yanlışlıkla değiştirilmesini engeller. let ise, dinamik gereksinimleri karşılarken var'ın getirdiği kapsam (scope) karmaşıklıklarından kaçınmanızı sağlar. Bu modern pratikler, JavaScript ekosisteminde kabul görmüş standartlar haline gelmiştir.

Uzman İpucu: Bir değişkene karar verirken her zaman önce const kullanmayı düşünün. Eğer değerini değiştirmek zorundaysanız, o zaman let'e geçin. var'ı ise modern projelerde neredeyse hiç kullanmamanız şiddetle tavsiye edilir. Bu, kodunuzun daha öngörülebilir ve hatasız olmasını sağlar.

Değiğişken İsimlendirme Kuralları ve En İyi Uygulamalar Nelerdir?

JavaScript'te değişken tanımlamak kadar, onlara anlamlı ve kurallara uygun isimler vermek de büyük önem taşır. Değişken isimleri, kodun okunabilirliğini, anlaşılabilirliğini ve bakımını doğrudan etkiler. Kötü isimlendirilmiş bir değişken, gelecekteki bir geliştirici (hatta kendiniz bile!) için kodu anlamayı ve hata ayıklamayı kabusa çevirebilir. Bu nedenle, JavaScript'in değişken isimlendirme kurallarına uymanın yanı sıra, sektördeki en iyi pratikleri de benimsemek kritik bir beceridir.

JavaScript Değişken İsimlendirme Kuralları

JavaScript motoru tarafından zorunlu kılınan bazı temel kurallar vardır:

  • Harfler, Rakamlar, Alt Çizgi (_) ve Dolar İşareti ($): Değişken isimleri bu karakterleri içerebilir.
  • Sayı ile Başlayamaz: Değişken isimleri bir sayı ile başlayamaz (örneğin, 1numara geçersizdir).
  • Boşluk İçeremez: Değişken isimlerinde boşluk kullanılamaz (örneğin, kullanici adi geçersizdir).
  • Büyük/Küçük Harf Duyarlılığı: JavaScript büyük/küçük harfe duyarlıdır. Yani, mesaj, Mesaj ve MESAJ üç farklı değişkendir.
  • Rezerv Kelimelerden Kaçınma: JavaScript'in kendi anahtar kelimeleri (reserved keywords) değişken ismi olarak kullanılamaz. Örneğin, for, while, function, let, const, var, if, else, return gibi kelimeler kullanılamaz.

Geçersiz ve Geçerli İsimlendirme Örnekleri:


  // Geçerli İsimler
  let kullaniciAdi = "Ali";
  let _telefonNumarasi = "5551234567";
  let $fiyat = 99.99;
  let toplam_maliyet = 250;
  let mesaj9 = "Merhaba";

  // Geçersiz İsimler (hata verir)
  // let 1urun = "Elma"; // Sayı ile başlıyor
  // let ilk urun = "Armut"; // Boşluk içeriyor
  // let for = "döngü"; // Rezerv kelime
  // let const = "sabit"; // Rezerv kelime

Değişken İsimlendirmede En İyi Uygulamalar (Konvansiyonlar)

Kurallara uymak yeterli değildir; kodun kalitesini artırmak için belirli isimlendirme konvansiyonlarına uymak da önemlidir.

  1. CamelCase (camelCase): JavaScript'te en yaygın kullanılan isimlendirme konvansiyonudur. İlk kelime küçük harfle başlar, sonraki kelimelerin ilk harfleri büyük olur. Değişkenler ve fonksiyonlar için kullanılır.
    
          let toplamSiparisAdedi = 15;
          let urunFiyatiHesapla = (adet, fiyat) => adet * fiyat;
        

  2. PascalCase (PascalCase): Her kelimenin ilk harfi büyük harfle başlar. Genellikle sınıf isimleri ve yapıcı fonksiyonlar (constructor functions) için kullanılır.
    
          class KullaniciProfil { /* ... */ }
          function SiparisDetay(urun, adet) { /* ... */ }
        

  3. Snake_case (snake_case): Kelimeler alt çizgi ile ayrılır. Bazı dillerde (Python gibi) yaygın olsa da, JavaScript'te genellikle sabitler dışında tercih edilmez.
    
          // Genellikle diğer dillerde veya sabitlerde kullanılır.
          // let toplam_tutar = 100; // JavaScript'te pek yaygın değil
        

  4. Kebab-case (kebab-case): Kelimeler tire ile ayrılır. HTML/CSS'de yaygın olsa da, JavaScript değişken isimleri için kullanılamaz çünkü tire çıkarma operatörü olarak yorumlanır.
  5. Büyük Harflerle ve Alt Çizgi ile (UPPER_SNAKE_CASE): const ile tanımlanmış, değeri hiç değişmeyecek gerçek sabitler için kullanılır.
    
          const MAX_OGRENCI_SAYISI = 30;
          const API_KEY = "abcxyz123";
        

Anlaşılır ve Açıklayıcı İsimler Kullanmanın Önemi

Değişken isimleri, ne anlama geldiklerini ve ne işe yaradıklarını net bir şekilde ifade etmelidir. Kısa ama anlamsız isimlerden kaçınılmalıdır.

  • Kötü Örnek: let x = 10; (x neyi temsil ediyor?)
  • İyi Örnek: let ogrenciSayisi = 10; (açıkça öğrenci sayısını belirtiyor)
  • Kötü Örnek: let data = fetch('...'); (hangi veri?)
  • İyi Örnek: let kullaniciVerileri = fetch('...'); (kullanıcıya ait veriler)

Ayrıca, değişken isimlerinde İngilizce kelimeler kullanmak, uluslararası projelerde veya takım çalışmalarında daha yaygın ve tercih edilen bir yaklaşımdır. Ancak, eğer proje tamamen Türkçe konuşan bir ekip tarafından geliştiriliyorsa ve sadece bu ekibin kullanımına yönelikse Türkçe isimler de tercih edilebilir. Önemli olan, tutarlı olmaktır.

Sonuç olarak, değişken isimlendirme, sadece kodun çalışmasını sağlayan bir detay değil, aynı zamanda kodun kalitesini, sürdürülebilirliğini ve takım içinde işbirliğini doğrudan etkileyen bir sanattır. İyi isimlendirilmiş kod, kendi kendini belgeleyen kod olarak kabul edilir ve gelecekte zaman ve emekten tasarruf etmenizi sağlar.

JavaScript'te Değişkenlerin Kapsamı (Scope): Nerede Erişebiliriz?

JavaScript'te değişkenlerin kapsamı veya "scope", bir değişkenin kodunuzun hangi bölümlerinden erişilebilir olduğunu belirleyen önemli bir kavramdır. Kapsam kuralları, değişkenlerin yaşam döngüsünü, çakışmaları ve potansiyel hataları kontrol etmede kilit rol oynar. Doğru kapsam yönetimi, kodunuzun daha güvenli, düzenli ve öngörülebilir olmasını sağlar. JavaScript'te üç ana scope türü vardır: Global scope, Function scope ve Block scope. Bu kapsamlar, var, let ve const anahtar kelimeleriyle tanımlanan değişkenlerin davranışlarını doğrudan etkiler.

Global Scope: Her Yerden Erişilebilir Değişkenler

Global scope'ta tanımlanan değişkenler, JavaScript kodunun herhangi bir yerinden erişilebilir. Bir değişkeni herhangi bir fonksiyonun veya bloğun dışında tanımladığınızda, o değişken otomatik olarak global scope'a ait olur. Global değişkenler, uygulamanızın farklı bölümleri arasında veri paylaşımı için kullanışlı olabilir, ancak aynı zamanda dikkatli kullanılmadığında istenmeyen yan etkilere yol açma potansiyeli taşır. Çok sayıda global değişken kullanmak, isim çakışmalarına (naming collisions) ve kodun karmaşık hale gelmesine neden olabilir.


  let globalMesaj = "Bu global bir mesajdır."; // Global scope

  function birinciFonksiyon() {
    console.log(globalMesaj); // Global değişkene erişim
    globalMesaj = "Mesaj birinci fonksiyonda değişti.";
  }

  function ikinciFonksiyon() {
    console.log(globalMesaj); // Değişen global mesajı görür
  }

  birinciFonksiyon(); // Global mesajı değiştirir
  ikinciFonksiyon();  // "Mesaj birinci fonksiyonda değişti." çıktısını verir

Görüldüğü gibi, globalMesaj değişkenine her iki fonksiyondan da erişebildik ve hatta bir fonksiyondan değiştirdiğimizde diğer fonksiyon da bu değişikliği algıladı. Bu durumun faydaları olduğu kadar, büyük uygulamalarda hangi fonksiyonun hangi global değişkeni değiştirdiğini takip etmenin zorlaşması gibi dezavantajları da vardır.

Function Scope: Fonksiyonlara Özel Değişkenler (var ile)

var anahtar kelimesi ile tanımlanan değişkenler 'function scope'a sahiptir. Bu, bir var değişkeninin yalnızca tanımlandığı fonksiyon içinde veya iç içe geçmiş fonksiyonlarda erişilebilir olduğu anlamına gelir. Fonksiyon dışından bu değişkenlere erişmeye çalışmak bir referans hatasına (ReferenceError) yol açar. Bu, değişkenleri belirli bir işlevsel birim içinde izole etmenin ve isim çakışmalarını azaltmanın bir yoludur.


  function hesaplaToplam(s1, s2) {
    var toplam = s1 + s2; // toplam function scope'ta
    console.log("Fonksiyon içinde toplam:", toplam);
  }

  hesaplaToplam(5, 7); // "Fonksiyon içinde toplam: 12"
  // console.log("Fonksiyon dışında toplam:", toplam); // Hata: toplam is not defined

Function scope, bir fonksiyonun kendi iç işleyişini dış dünyadan korumak için doğal bir mekanizma sağlar. toplam değişkeni, hesaplaToplam fonksiyonunun dış dünyadan bağımsız çalışmasını garanti eder.

Block Scope: Modern ve Hassas Kontrol (let ve const ile)

let ve const anahtar kelimeleri, ES6 ile birlikte 'block scope' kavramını getirmiştir. Block scope, süslü parantezlerle {} tanımlanan her blok için (örneğin if ifadeleri, for döngüleri, while döngüleri veya basit bir kod bloğu) ayrı bir kapsam oluşturur. let veya const ile tanımlanan değişkenler yalnızca o bloğun içinde ve alt bloklarında erişilebilir. Bu, değişkenlerin yaşam süresini çok daha hassas bir şekilde kontrol etmemizi sağlar ve var'ın neden olduğu birçok kapsam sorununu ortadan kaldırır.


  if (true) {
    let ad = "Mehmet"; // Block scope'ta
    const soyad = "Yılmaz"; // Block scope'ta
    var sehir = "Ankara"; // Function/Global scope'ta (blok içindeki var!)
    console.log(ad, soyad, sehir); // Mehmet Yılmaz Ankara
  }

  // console.log(ad); // Hata: ad is not defined (blok dışından erişilemez)
  // console.log(soyad); // Hata: soyad is not defined (blok dışından erişilemez)
  console.log(sehir); // Ankara (var olduğu için blok dışından erişilebilir!)

  for (let i = 0; i < 3; i++) {
    // i her iterasyonda yeniden tanımlanmaz, ancak her döngü için ayrı bir i kapsamı oluşur.
    console.log(Döngü içi i: ${i});
  }
  // console.log(i); // Hata: i is not defined (döngü bloğu dışından erişilemez)

Bu örnek, let ve const'un neden modern JavaScript'te tercih edildiğini net bir şekilde gösterir. Değişkenlerin belirli bir blokla sınırlı olması, kodun daha öngörülebilir olmasını ve istenmeyen yan etkilerin önüne geçilmesini sağlar. Özellikle döngülerde, var kullanıldığında oluşan "kapanış sorunu" (closure issue) let ile doğal olarak çözülür, çünkü her döngü iterasyonu kendi i değişkenine sahip olur.

Uzman İpucu: Kapsam hatalarını önlemek için mümkün olduğunca dar kapsamlı değişkenler kullanın. Yani, bir değişkeni sadece ihtiyaç duyulan en küçük blok içinde tanımlayın. Bu, kodun bakımını kolaylaştırır, hata olasılığını azaltır ve kodun daha modüler olmasını sağlar.

Vaka Analizi: Scope Hatalarını Önleme

Bir web uygulamasında genellikle birçok fonksiyon ve blok bulunur. Eğer değişken kapsamını doğru anlamazsanız, kolayca hatalar yapabilirsiniz. Örneğin, bir form gönderimi işleyicisi yazdığınızı varsayalım:


  let kullaniciVerisi = {}; // Global veya daha geniş kapsamlı bir değişken

  function formGonder() {
    let inputAd = document.getElementById("ad").value;
    let inputEmail = document.getElementById("email").value;

    if (inputAd && inputEmail) {
      kullaniciVerisi = {
        ad: inputAd,
        email: inputEmail
      };
      console.log("Form verileri kaydedildi:", kullaniciVerisi);
    } else {
      console.log("Lütfen tüm alanları doldurun.");
    }

    // console.log(inputAd); // Bu satır fonksiyonda olduğu için erişilebilir
  }
  // console.log(inputAd); // Hata: inputAd is not defined (fonksiyon dışından erişilemez)

Bu senaryoda, inputAd ve inputEmail değişkenleri formGonder fonksiyonunun kapsamındadır. Bu değişkenlere fonksiyon dışından erişmeye çalışmak hata verecektir, ki bu genellikle istenen davranıştır. kullaniciVerisi ise daha geniş bir kapsamda tanımlanarak farklı fonksiyonların da bu verilere erişmesini sağlar. Doğru kapsam yönetimi sayesinde, farklı fonksiyonların aynı isimde değişkenleri kullanması durumunda bile çakışmaların önüne geçilir ve kodunuz daha güvenli hale gelir.

Özetle, JavaScript'te kapsam, değişkenlerin erişilebilirliğini ve yaşam döngüsünü kontrol eden temel bir mekanizmadır. var, let ve const arasındaki seçim, bu kapsam kurallarını nasıl uygulayacağınızı ve kodunuzun ne kadar güvenli ve düzenli olacağını doğrudan etkiler. Modern uygulamalarda, let ve const kullanarak block scope'un avantajlarından faydalanmak, daha temiz ve sürdürülebilir kod yazmanın anahtarıdır.

Değişken Türleri ve Tip Dönüşümleri Nasıl Çalışır?

JavaScript, 'dinamik tipli' bir dildir. Bu, bir değişken tanımlarken belirli bir veri tipi belirtmenize gerek olmadığı anlamına gelir. JavaScript motoru, değişkene atanan değere göre otomatik olarak veri tipini belirler. Ayrıca, aynı değişken, programın farklı noktalarında farklı tiplerde değerler alabilir. Bu esneklik, hızlı geliştirmeye olanak tanırken, tip dönüşümlerini ve farklı veri tiplerini anlamayı kritik hale getirir. JavaScript'te temelde iki tür veri tipi kategorisi bulunur: ilkel (primitive) tipler ve ilkel olmayan (non-primitive) tipler.

İlkel (Primitive) Veri Tipleri

İlkel tipler, basit ve tek bir değer depolayan tiplerdir. Bir değişkene ilkel bir değer atandığında, değerin kendisi kopyalanır.

  • String (Metin): Tırnak işaretleri ('' veya "") arasına yazılan metinlerdir.
    
          let ad = "Can";
          let selam = 'Merhaba Dünya!';
        

  • Number (Sayı): Hem tam sayıları hem de ondalıklı sayıları kapsar.
    
          let yas = 30;
          let pi = 3.14;
        

  • Boolean (Mantıksal): Sadece true (doğru) veya false (yanlış) değerlerini alabilen tiplerdir. Koşullu ifadelerde sıkça kullanılır.
    
          let yetkiliMi = true;
          let aktifMi = false;
        

  • Undefined (Tanımsız): Bir değişken tanımlandığında ancak ona herhangi bir değer atanmadığında otomatik olarak aldığı tiptir. Ayrıca bir fonksiyondan bir değer döndürülmediğinde de bu tip değer döner.
    
          let tanimsizDegisken; // değeri undefined
          console.log(tanimsizDegisken); // undefined
        

  • Null (Boş): Bilerek atanmış "değer yok" anlamına gelen özel bir tiptir. undefined'dan farklı olarak, null bir geliştirici tarafından bilinçli olarak atanır.
    
          let bosDeger = null;
          console.log(bosDeger); // null
        

  • Symbol (Sembol): ES6 ile tanıtılmış benzersiz ve değiştirilemez bir değer oluşturmak için kullanılır. Nesne özelliklerinin çakışmasını önlemek için idealdir.
    
          const id = Symbol('kimlik');
          const id2 = Symbol('kimlik');
          console.log(id === id2); // false (her Symbol benzersizdir)
        

  • BigInt (Büyük Tam Sayı): ES2020 ile gelmiş olup, Number tipinin ifade edebileceği en büyük tam sayıdan (253 - 1) daha büyük tam sayıları temsil etmek için kullanılır. n son eki ile tanımlanır.
    
          let buyukSayi = 9007199254740991n; // 'n' ile BigInt olarak tanımlanır
        

İlkel Olmayan (Non-Primitive) Veri Tipleri

İlkel olmayan tipler, birden fazla değeri veya daha karmaşık yapıları depolayabilen tiplerdir. Bir değişkene ilkel olmayan bir değer atandığında, değerin kendisi yerine bellekteki referansı kopyalanır.

  • Object (Nesne): JavaScript'teki hemen hemen her şey (diziler, fonksiyonlar dahil) nesnedir. Key-value çiftlerinden oluşan bir koleksiyondur.
    
          let kullanici = {
            ad: "Zeynep",
            yas: 28,
            email: "zeynep@example.com"
          };
        

  • Array (Dizi): Sıralı bir veri koleksiyonudur ve nesnelerin özel bir türüdür.
    
          let renkler = ["kırmızı", "yeşil", "mavi"];
        

  • Function (Fonksiyon): Çalıştırılabilir kod bloklarıdır ve JavaScript'te "first-class citizens" olarak kabul edilirler, yani değişkenlere atanabilir, argüman olarak geçirilebilir ve fonksiyonlardan döndürülebilirler.
    
          function selamVer() {
            console.log("Merhaba!");
          }
        

Tip Dönüşümleri (Type Coercion)

JavaScript'in dinamik tipli doğası, çoğu zaman tip dönüşümlerini beraberinde getirir. Tip dönüşümü, bir veri tipinin başka bir veri tipine dönüştürülmesi işlemidir. Bu dönüşümler iki şekilde gerçekleşebilir:

  1. Implicit (Otomatik) Tip Dönüşümü: JavaScript motorunun otomatik olarak gerçekleştirdiği dönüşümlerdir. Genellikle operatörler veya fonksiyonlar farklı tiplerdeki değerlerle karşılaştığında tetiklenir.
    
          let sayi = 5;
          let metin = "10";
          let sonuc = sayi + metin; // '510' (sayı string'e dönüşür ve birleştirme yapılır)
          console.log(typeof sonuc); // string
    
          let bool = true;
          let num = 1;
          let sonuc2 = bool + num; // 2 (true, 1'e dönüşür)
          console.log(sonuc2);
    
          let strSayi = "20";
          let bolum = strSayi / 2; // 10 (string, sayıya dönüşür ve bölme yapılır)
          console.log(bolum);
        

    Bu otomatik dönüşümler bazen kafa karıştırıcı olabilir ve beklenmedik sonuçlara yol açabilir. Özellikle + operatörü hem sayısal toplama hem de string birleştirme yapabildiği için dikkatli olunmalıdır.

  2. Explicit (Açık) Tip Dönüşümü: Geliştiricinin bilinçli olarak bir tipi başka bir tipe dönüştürmesidir. Bunun için çeşitli global fonksiyonlar veya metotlar kullanılır.
    • String'e Dönüştürme:
      
                let numToString = String(123); // "123"
                let boolToString = (true).toString(); // "true"
              

    • Number'a Dönüştürme:
      
                let strToNum = Number("456"); // 456
                let strToInt = parseInt("789.5"); // 789
                let strToFloat = parseFloat("12.34"); // 12.34
                // Boş string veya sadece boşluk içeren string 0'a, diğer geçersiz stringler NaN'a (Not-a-Number) dönüşür.
                console.log(Number("")); // 0
                console.log(Number("merhaba")); // NaN
              

    • Boolean'a Dönüştürme:
      
                let numToBool = Boolean(0); // false (0, null, undefined, "", NaN false'a dönüşür)
                let strToBool = Boolean("hello"); // true (boş olmayan stringler true'ya dönüşür)
                let objToBool = Boolean({}); // true (boş nesneler ve diziler de true'dur)
              

Tip dönüşümlerini anlamak ve gerektiğinde açık dönüşümleri kullanmak, JavaScript kodunuzu daha sağlam ve güvenilir hale getirir. Otomatik dönüşümlerin sebep olabileceği sürprizlerden kaçınmak için, özellikle matematiksel işlemler veya karşılaştırmalar yaparken veri tiplerinden emin olmak ve gerekirse açıkça dönüştürmek en iyi uygulamadır. Örneğin, kullanıcıdan alınan girdiler her zaman string olarak gelir, bu yüzden sayısal işlem yapmadan önce Number() veya parseInt() ile sayıya dönüştürmek güvenli bir yaklaşımdır.

Gerçek Dünya Senaryolarında JavaScript Değişken Kullanımı: Bir Vaka Analizi

Değişkenlerin teorik bilgilerini öğrendikten sonra, bu bilgileri gerçek bir senaryoda nasıl uygulayacağımızı görmek, konuyu pekiştirmenin en iyi yoludur. Basit bir interaktif alışveriş sepeti uygulamasının temelini atarak, var, let, const ve farklı veri tiplerinin pratikte nasıl kullanıldığını inceleyelim. Bu vaka analizi, aynı zamanda mobil uyumlu bir HTML yapısının değişkenlerle nasıl etkileşim kurduğunu da gösterecektir.

Senaryo: Basit Bir Alışveriş Sepeti Uygulaması

Bir e-ticaret sitesinde, kullanıcıların ürünleri sepete ekleyebileceği, miktarını değiştirebileceği ve toplam tutarı görebileceği basit bir alışveriş sepeti modülü geliştireceğiz. Bu modülde, ürün bilgileri, sepet durumu ve kullanıcı etkileşimleri için değişkenleri etkin bir şekilde kullanacağız.

1. Sabit Değerler (const ile)

Uygulamamızda bazı değerler sabit kalacak. Örneğin, KDV oranı veya ürünlerin başlangıç fiyatları. Bu tür değerler için const kullanmak, onların yanlışlıkla değiştirilmesini engeller ve kodun güvenliğini artırır.


  const KDV_ORANI = 0.18; // %18 KDV oranı, değeri değişmeyecek
  const FIYAT_KALEM_1 = 120.00; // İlk ürünün sabit fiyatı
  const FIYAT_KALEM_2 = 75.50;  // İkinci ürünün sabit fiyatı
  const PARA_BIRIMI = "TL";   // Para birimi

Burada KDV_ORANI, FIYAT_KALEM_1, FIYAT_KALEM_2 ve PARA_BIRIMI gibi değerler uygulamanın ömrü boyunca sabit kalacaktır. const kullanmak, hem geliştiriciye bu değerlerin niyetini açıkça belirtir hem de JavaScript motorunun bu değişkenleri optimize etmesine yardımcı olabilir.

2. Değişken Değerler (let ile)

Sepetteki ürün miktarı, toplam sepet tutarı veya kullanıcı tarafından girilen indirim kodu gibi değerler uygulama içinde sürekli değişebilir. Bu tür dinamik değerler için let kullanmak en uygun yaklaşımdır.


  let urun1Miktari = 0; // Başlangıçta 0 adet
  let urun2Miktari = 0; // Başlangıçta 0 adet
  let toplamSepetTutari = 0;
  let indirimKodu = ""; // Kullanıcının girebileceği indirim kodu
  let uygulanacakIndirimOrani = 0; // Varsayılan indirim yok

Kullanıcı "Sepete Ekle" butonuna tıkladıkça urun1Miktari veya urun2Miktari değişkenleri artırılacak, bu da toplamSepetTutari'nı güncelleyecektir. Örneğin:


  function urun1AdetArtir() {
    urun1Miktari++; // Miktarı artır
    sepetiGuncelle();
  }

  function urun2AdetAzalt() {
    if (urun2Miktari > 0) {
      urun2Miktari--; // Miktarı azalt
      sepetiGuncelle();
    }
  }

  function sepetiGuncelle() {
    let brutToplam = (urun1Miktari * FIYAT_KALEM_1) + (urun2Miktari * FIYAT_KALEM_2);
    let kdvTutari = brutToplam * KDV_ORANI;
    let indirimTutari = brutToplam * uygulanacakIndirimOrani;
    toplamSepetTutari = brutToplam + kdvTutari - indirimTutari;

    // Arayüzü güncelleme (örneğin HTML elementlerinin içeriğini değiştirme)
    document.getElementById("urun1-miktar").innerText = urun1Miktari;
    document.getElementById("urun2-miktar").innerText = urun2Miktari;
    document.getElementById("toplam-tutar").innerText = toplamSepetTutari.toFixed(2) + " " + PARA_BIRIMI;
  }

  // Örneğin, bir indirim kodu uygulandığında
  function indirimUygula(kod) {
    if (kod === "YAZINDIRIMI") {
      uygulanacakIndirimOrani = 0.10; // %10 indirim
      indirimKodu = kod;
      console.log("YAZINDIRIMI uygulandı!");
    } else {
      uygulanacakIndirimOrani = 0;
      indirimKodu = "";
      console.log("Geçersiz indirim kodu.");
    }
    sepetiGuncelle();
  }

Bu örnekte, let ile tanımlanan değişkenlerin değerleri, kullanıcı etkileşimlerine ve uygulama mantığına göre dinamik olarak güncellenmektedir. Fonksiyonlar içindeki brutToplam, kdvTutari, indirimTutari gibi geçici hesaplama değişkenleri de let ile tanımlanır, çünkü bunlar sadece o fonksiyonun yürütülmesi sırasında geçerlidir ve değerleri hesaplama sürecinde değişebilir.

3. HTML Yapısı ve Mobil Uyumluluk

Bu değişkenleri gösteren ve kullanıcı etkileşimini sağlayan HTML yapısı da önemlidir. Değişkenler, genellikle DOM (Document Object Model) elementlerinin içeriğini veya özelliklerini dinamik olarak değiştirmek için kullanılır. Modern web geliştirme, mobil uyumlu (responsive) tasarıma önem verir. HTML yapınızı mobil cihazlarda da iyi görünecek şekilde tasarlarken, JavaScript değişkenlerinizin doğrudan bir etkisi olmasa da, onların DOM manipülasyonları aracılığıyla içeriği dinamik olarak nasıl güncellediği, kullanıcı deneyimini etkiler. Örneğin, sepetiGuncelle() fonksiyonu, document.getElementById("toplam-tutar").innerText gibi yöntemlerle HTML elementlerinin içeriğini günceller. HTML yapısını mobil uyumlu şekilde oluşturarak (örneğin, esnek kutular flexbox veya ızgara grid kullanarak), JavaScript ile güncellenen içeriğin farklı ekran boyutlarında sorunsuz görünmesini sağlayabiliriz.


  

Alışveriş Sepeti

Ürün 1 (Fiyat: 120.00 TL) Miktar: 0
Ürün 2 (Fiyat: 75.50 TL) Miktar: 0

Toplam Tutar: 0.00 TL

Bu vaka analizi, const ve let değişkenlerinin bir araya gelerek nasıl dinamik ve işlevsel bir web uygulaması oluşturabildiğini göstermektedir. const, tahmin edilebilir ve güvenli sabitler sağlarken, let kullanıcının etkileşimlerine göre değişen uygulama durumunu yönetir. Bu yapı, kodun okunabilirliğini, bakımını ve hata ayıklamasını kolaylaştırır. var ise bu modern yaklaşımlarda nadiren tercih edilir, çünkü sunduğu kapsam kuralları, genellikle karmaşık uygulamalarda beklenmeyen davranışlara yol açabilir.

İleri Düzey Değişken Yönetimi İpuçları ve Püf Noktaları Nelerdir?

JavaScript'te değişkenlerin temellerini ve var, let, const farklarını anladıktan sonra, kodunuzu daha verimli, okunabilir ve sürdürülebilir hale getirecek bazı ileri düzey değişken yönetimi tekniklerine geçebiliriz. Bu ipuçları, özellikle büyük ölçekli uygulamalar geliştirirken veya daha karmaşık veri yapılarıyla çalışırken size yardımcı olacaktır.

1. Destructuring Assignment (Yapı Bozma Ataması)

Destructuring, ES6 ile gelen güçlü bir özelliktir. Dizilerden veya nesnelerden veri ayıklamanın ve bunları ayrı değişkenlere atamanın daha kısa ve okunaklı bir yolunu sunar. Bu, özellikle bir fonksiyondan dönen bir nesneden belirli özelliklere veya bir diziden belirli elemanlara erişmek istediğinizde çok kullanışlıdır.


  // Nesne Destructuring
  const kullaniciBilgisi = {
    ad: "Elif",
    soyad: "Demir",
    yas: 29,
    adres: {
      il: "İstanbul",
      ilce: "Kadıköy"
    }
  };

  // Eskiden:
  // const ad = kullaniciBilgisi.ad;
  // const yas = kullaniciBilgisi.yas;

  // Destructuring ile:
  const { ad, yas, email = "bilgi@yok.com" } = kullaniciBilgisi; // email için varsayılan değer
  console.log(ad, yas, email); // Elif 29 bilgi@yok.com

  // İç içe nesneler için destructuring:
  const { adres: { il, ilce } } = kullaniciBilgisi;
  console.log(il, ilce); // İstanbul Kadıköy

  // Dizi Destructuring
  const renkler = ["kırmızı", "yeşil", "mavi"];

  // Eskiden:
  // const birinciRenk = renkler[0];
  // const ikinciRenk = renkler[1];

  // Destructuring ile:
  const [birinciRenk, ikinciRenk, ucuncuRenk] = renkler;
  console.log(birinciRenk, ikinciRenk, ucuncuRenk); // kırmızı yeşil mavi

  // Belirli elemanları atlama veya kalanları alma (rest operator ile)
  const [ilk, , ucuncu, ...kalanlar] = ["a", "b", "c", "d", "e"];
  console.log(ilk, ucuncu, kalanlar); // a c ["d", "e"]

Destructuring, kodun daha derli toplu ve ne yaptığını açıkça gösteren bir yapıya sahip olmasını sağlar.

2. Spread (...) ve Rest (...) Operatörü ile Değişken Yönetimi

ES6 ile tanıtılan Spread ve Rest operatörleri, diziler ve nesnelerle çalışırken değişken yönetimini büyük ölçüde basitleştirir.

  • Spread Operatörü (...): Bir diziyi veya nesneyi "yayarak" elemanlarını veya özelliklerini başka bir diziye/nesneye kopyalamaya veya bir fonksiyonun argüman listesine genişletmeye yarar.
    
          const arr1 = [1, 2, 3];
          const arr2 = [4, 5, 6];
          const birlesikDizi = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]
    
          const obj1 = { a: 1, b: 2 };
          const obj2 = { c: 3, d: 4 };
          const birlesikNesne = { ...obj1, ...obj2 }; // { a: 1, b: 2, c: 3, d: 4 }
    
          // Bir nesneyi kopyalayıp yeni özellik eklemek veya değiştirmek:
          const orijinalAyarlar = { tema: "dark", dil: "tr" };
          const yeniAyarlar = { ...orijinalAyarlar, tema: "light", bildirimler: true };
          // { tema: "light", dil: "tr", bildirimler: true }
        

  • Rest Operatörü (...): Bir fonksiyona geçirilen kalan tüm argümanları bir diziye toplamak veya bir nesneden bazı özellikleri ayıklayıp kalanları yeni bir nesneye toplamak için kullanılır. Destructuring ile karıştırılmamalıdır, kullanıldığı yere göre anlamı değişir.
    
          // Fonksiyon argümanlarında Rest
          function topla(ilkSayi, ...digerSayilar) { // diğerSayilar bir dizi olacak
            return ilkSayi + digerSayilar.reduce((acc, current) => acc + current, 0);
          }
          console.log(topla(1, 2, 3, 4)); // 10 (ilkSayi=1, digerSayilar=[2,3,4])
    
          // Nesne Destructuring ile Rest
          const { ad, ...kalanOzellikler } = kullaniciBilgisi;
          console.log(ad, kalanOzellikler); // Elif { soyad: "Demir", yas: 29, adres: { il: "İstanbul", ilce: "Kadıköy" } }
        

Bu operatörler, dizileri ve nesneleri manipüle etmeyi çok daha esnek ve okunaklı hale getirir.

3. Global Değişkenlerden Kaçınma (Side Effects)

Daha önce bahsettiğimiz gibi, global değişkenler kodun herhangi bir yerinden erişilebilir ve değiştirilebilir. Bu durum, "side effect" adı verilen yan etkilere yol açabilir. Yani, bir fonksiyonun global bir değişkeni beklenmedik bir şekilde değiştirmesi, uygulamanızın başka bir yerinde hatalara neden olabilir. Mümkün olduğunca değişkenleri yerel scope'larda (block veya function scope) tutmaya çalışın. Bu, kodun daha modüler, test edilebilir ve izole olmasını sağlar.


  // Kötü pratik: Global bir sayaç
  let sayac = 0; // Global değişken

  function artir() {
    sayac++; // Global değişkeni değiştiriyor (side effect)
  }

  artir();
  artir();
  console.log(sayac); // 2

  // Daha iyi pratik: Yerel scope ve parametreler
  function artirGuvenli(mevcutSayac) {
    return mevcutSayac + 1; // Yeni bir değer döndür, dışarıyı etkileme
  }

  let yeniSayac = 0;
  yeniSayac = artirGuvenli(yeniSayac);
  yeniSayac = artirGuvenli(yeniSayac);
  console.log(yeniSayac); // 2

4. Hoisting'in Dikkat Edilmesi Gereken Yanları

var ile tanımlanan değişkenler ve fonksiyon bildirimleri, kapsamlarının en üstüne taşınır (hoisting). Ancak let ve const da teknik olarak hoisting'e tabidir, sadece 'Temporal Dead Zone (TDZ)' nedeniyle tanımlanmadan önce erişilemezler. Bu, kodunuzu yazarken değişkenlerin nerede tanımlandığına dikkat etmeniz gerektiği anlamına gelir. Genellikle, tüm değişken tanımlamalarını (özellikle let ve const ile) ilgili scope'un en başında yapmak iyi bir uygulamadır, bu da kodun okunabilirliğini artırır ve TDZ ile ilgili hataları önler.

5. use strict Kullanımı

Modern JavaScript'te use strict direktifi, kodunuzu "katı modda" çalıştırmanızı sağlar. Bu, JavaScript motorunun bazı "gevşek" veya "sessiz" hataları (örneğin, tanımlanmamış bir değişkene değer atamak gibi) hata olarak ele almasını sağlar. use strict'i bir dosyanın veya fonksiyonun en başına eklemek, daha güvenli ve hata ayıklaması kolay kod yazmanıza yardımcı olur. Özellikle değişkenlerin yanlışlıkla global scope'a sızmasını engellemeye yardımcı olur.


  "use strict"; // Dosyanın veya fonksiyonun başında
  // degisken = 10; // Hata: 'degisken' tanımlanmamış
  let degisken = 10; // Doğru kullanım

Bu ileri düzey ipuçları ve püf noktaları, değişkenleri sadece depolama aracı olarak görmekten öteye geçmenizi, onları kodunuzun mimarisini şekillendiren güçlü araçlar olarak kullanmanızı sağlar. Temiz kod, güvenilir kod demektir ve bu teknikler, bu hedefe ulaşmanıza yardımcı olacaktır.

Sonuç: JavaScript Programlamasında Değişkenlerin Rolü

Bu kapsamlı makalede, JavaScript değişkenlerinin neden bir programın temel taşı olduğunu, var, let ve const anahtar kelimelerinin altında yatan farkları ve bu farkların kodunuzun kapsam (scope) üzerindeki etkilerini ayrıntılı bir şekilde inceledik. Gördük ki, değişkenler sadece veriyi depolayan kutular değil, aynı zamanda kodun akışını, okunabilirliğini, bakımını ve güvenilirliğini doğrudan etkileyen kritik unsurlardır. const ile sabit değerleri, let ile dinamik olarak değişen değerleri yönetmek, modern JavaScript geliştirme pratiğinin vazgeçilmez bir parçası haline gelmiştir. var ise, yerini daha güvenli ve öngörülebilir let ve const'a bırakmıştır.

Değişken isimlendirme kurallarına uymak ve anlamlı isimler kullanmak, kodunuzun kendi kendini belgeleyen bir yapıya sahip olmasını sağlar. Kapsam (global, function, block) kurallarını iyi anlamak, özellikle büyük uygulamalarda ortaya çıkabilecek beklenmedik hataları ve yan etkileri önlemenin anahtarıdır. Ayrıca, JavaScript'in dinamik tipli yapısını ve tip dönüşümlerini kavramak, veri manipülasyonunda karşılaşabileceğiniz sürprizleri en aza indirir. Son olarak, destructuring assignment, spread/rest operatörleri gibi ileri düzey teknikler ve global değişkenlerden kaçınma prensibi, daha temiz, daha esnek ve daha sürdürülebilir JavaScript kodu yazmanızı sağlayacaktır. Unutmayın, iyi yönetilmiş değişkenler, hatasız ve güçlü uygulamalar geliştirmenin temelini oluşturur. Bu bilgileri pratiğe dökerek JavaScript'teki yetkinliğinizi artırmaya devam edin!

Sıkça Sorulan Sorular (SSS)

1. var anahtar kelimesini hala kullanmalı mıyım?

Modern JavaScript geliştirme pratiklerinde var kullanmak genellikle tavsiye edilmez. var'ın function scope'u ve hoisting davranışı, beklenmedik hatalara ve kod karmaşıklığına yol açabilir. Bunun yerine, değerini değiştiremeyeceğiniz durumlarda const, değiştirebileceğiniz durumlarda ise let kullanmanız önerilir. Bu yaklaşım, kodunuzu daha güvenli, öngörülebilir ve okunabilir kılar.

2. const ile tanımlanmış bir obje veya dizi tamamen değiştirilemez mi yapar?

Hayır, const bir objeyi veya diziyi tamamen değiştirilemez yapmaz. const, sadece değişkenin *referansının* sabit kalmasını sağlar. Yani, o değişkene başka bir obje veya dizi *yeniden atayamazsınız*. Ancak, objenin içindeki özelliklerini değiştirebilir veya dizinin elemanlarını ekleyebilir/silebilirsiniz, çünkü objenin/dizinin kendisi (bellekteki adresi) değişmez, sadece içeriği değişir.

3. Değişkenleri tanımlarken her zaman bir değer atamak zorunda mıyım?

var ve let ile değişken tanımlarken ilk anda bir değer atamak zorunda değilsiniz. Eğer bir değer atanmazsa, değişkenin değeri otomatik olarak undefined olur. Ancak, const ile bir değişken tanımladığınızda, o anda bir değer atamanız zorunludur. Aksi takdirde bir SyntaxError hatası alırsınız, çünkü const sabit bir referans sağlamayı amaçlar ve başlangıçta bir değere sahip olması gerekir.

4. Hoisting nedir ve neden önemlidir?

Hoisting, JavaScript'in değişken ve fonksiyon bildirimlerini (tanımlamalarını) kapsayıcı scope'larının en üstüne taşıması davranışıdır. var ile tanımlanan değişkenlerin sadece bildirimleri taşınır ve başlangıç değeri undefined olur. let ve const da hoisting'e tabidir, ancak Temporal Dead Zone (TDZ) adı verilen bir mekanizma nedeniyle, tanımlanmadan önce erişilmeye çalışılırsa hata fırlatırlar. Hoisting, kodunuzu yazarken değişkenlerin sırasına dikkat etmenizi gerektirdiği için önemlidir; aksi takdirde beklenmedik undefined değerleriyle veya ReferenceError hatalarıyla karşılaşabilirsiniz.

5. Global değişkenler neden kötü kabul edilir?

Global değişkenler, kodunuzun herhangi bir yerinden erişilebilir ve değiştirilebilir oldukları için genellikle kötü bir pratik olarak kabul edilirler. Bunun başlıca nedenleri şunlardır: isim çakışmaları (farklı kod parçaları aynı isimde global değişkenler tanımlayabilir), bağımlılık yönetimi (hangi fonksiyonun hangi global değişkeni kullandığını/değiştirdiğini anlamak zorlaşır), ve yan etkiler (bir fonksiyonun global bir değişkeni değiştirmesi, uygulamanın başka bir yerinde beklenmedik davranışlara neden olabilir). Mümkün olduğunca değişkenleri dar kapsamlı (yerel veya block scope) tutmak, kodunuzu daha modüler, test edilebilir ve sürdürülebilir kılar.

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.