Javascript Değişkenler: var, let ve const
var
, let
ve const
arasındaki fark genelde interview'larda karşımıza çıkabilecek kafa karıştırıcı ve açıklaması zor bir konudur.
İlk olarak aralarındaki en büyük fark kapsam (scope) farkı. Şöyle ki;
var
== function kapsamılet
== block kapsamıconst
==let
gibi block kapsamı ancak immutable (değişmez)
Örneklerle anlamak gerekirse;
{ let number = 5 }
console.log(number) // ReferenceError: variable is not defined
{ var number = 5 }
console.log(number) // 5
const user = { name: 'Mehmet' }
user.name = 'Tayfun' // object özellikleri mutable'dır, const ile tanımlanmış bile olsa
console.log(user) // { name: 'Tayfun' }
user = { surname: 'Erbilen' } // TypeError: invalid assignment to const `user'
let
== block kapsamı
Tahmin edebileceğiniz gibi, bir kod bloğu içinde oluşur.
Çoğumuzda zaten değişkenlerin bu şekilde çalışmasını bekleriz, çünkü bir çok programlama dilinde sadece block kapsamı vardır.
Bir değişkenin erişimini sınırlamak ya da geçici olarak tanımlamak için değişkenleri let
ile oluşturmak uygundur.
Genelde çok sık verilen bir örneğe birlikte bakalım;
for ( var i = 1; <= 4; i++ ) {
console.log(i);
}
console.log(i); // 5
for ( let i = 1; <= 4; i++ ) {
console.log(i);
}
console.log(i); // ReferenceError: i is not defined
var
== function kapsamı
var
diğerlerinden biraz daha farklı çalışmaktadırç
Örnek vermek gerekirse;
var x = 5
function setX() {
var x = 10
console.log(x)
}
console.log(x) // 5
setX() // 10
console.log(x) // 5
bu örneği fonksiyon içinde var
kullanmadan yapmış olsaydık.
var x = 5
function setX() {
x = 10
console.log(x)
}
console.log(x) // 5
setX() // 10
console.log(x) // 10
const
== block kapsamı (immutable/değişmez)
let
gibi block kapsamındadır. Tek farkı yeni değer ataması yapılamaz.
Örneğin;
const URL = 'https://prototurk.com';
console.log(URL); // https://prototurk.com
URL = 'https://google.com'; TypeError: invalid assignment to const `URL'
Fakat değer olarak objeler mutable (değişebilir) dir.
Örneğin;
const User = {
name: 'Tayfun'
}
console.log(User)
User.name = 'Ahmet'
console.log(User)
Aynı şekilde diziler içinde bu durum geçerlidir;
const users = ['tayfun', 'mehmet', 'ahmet']
users.shift()
console.log(users)
users.append('süleyman')
console.log(users)
Eğer içindeki objelerinde immutable olmasını isterseniz Object.freeze()
kullanabilirsiniz.
const User = {
name: 'Tayfun'
}
console.log(User)
Object.freeze(User)
User.name = 'Ahmet'
console.log(User) // hata
Hoisting Terimi
Eğer bu terimi ilk defa duyduysanız sorun etmeyin, anlatınca anlaşılmayacak bir şey yok. Javascript kodları yorumlanırken fonksiyonlar ve var ile tanımlanmış değişkenler yukarı taşınırlar. Yani örneğin;
x = 10
console.log(x)
var x
console.log(x)
Bu örnek aslında şöyle yorumlanır
var x
x = 10
console.log(x)
console.log(x)
Dolayısı ile siz ikinci console log'un undefined
olacağını düşündüyseniz yanıldınız, yorunmlanırkenki haline bakınca aslında mantık oturuyor.
Ayrıca bir başka örneğide fonksiyonlar için verelim.
console.log(hello()) // hello world
function hello() {
return 'hello world'
}
console.log(hello())
bu da aynı şekilde şöyle yorumlanacaktır
var hello = function() {
return hello
}
console.log(hello())
console.log(hello())
bir başka örnek
console.log( x() * y() )
function x () {
return 5
}
function y () {
return 10
}
Dikkat edilmesi gereken, bu sürecin let
ve const
için geçerli olmadığıdır. Yani ilk örneği let
ya da const
ile deneyecek olursak sonuç şöyle olacaktı;
x = 10
console.log(x) // Cannot access 'x' before initialization
let x
console.log(x)
Değişkeni anahtar değersiz tanımlamak
Bir çılgınlık yapıp değişkeni şöyle tanımlarsanız
x = 'Tayfun'
O zaman javascript sizin için bu değişkeni global değişken olarak tanımlar. Bu da herkesin her yerden erişip değiştirebileceği anlamına gelir ve bu iyi bir şey değil.
Örneğin;
function sayHello() {
hello = 'hello'
}
console.log(hello) // ReferenceError: hello is not defined
sayHello()
console.log(helo) //
Sonuç olarak
var
-> global/function scopelet
-> block scopeconst
-> block scope ve immutable
Yani bir çok durum için const
yaygın olarak kullanılır. Geçici ya da kısıtlı işlemler için let
bunların çözemediği her durumda var
kullanın :D