Javascript Mutability ve Immutability Kavramları
⏳ Özet: Javascript'te bir değişken primitive ve reference olmak üzere 2 tip değer depolayabilir. Primitive tipler immutable'dır ve oluşturulduktan sonra program akışında değerleri korunur. Reference tipler ise mutable'dır ve oluşturulduktan sonra program akışında değerlerinin korunması garanti değildir. Javascript geliştirirken immutable değerler kullanmak paylaşılabilir değişkenleri azaltıp daha stabil bir uygulama geliştirme konusunda fayda sağlar.
Bu yazıda javascript geliştirirken çok dikkat etmediğimiz ve gözden kaçırabildiğimiz bir konu hakkında bilgi vermeye çalışacağım. Buna geçmeden önce neler öğreneceğimizi liste halinde görelim.
Neler Öğreneceğiz?
- Primitive ve Reference tipler nedir?
- Mutable ve Immutable kavramları nedir?
- Mutability ve Immutability arasındaki farklar
- ES6 ile immutable değerler nasıl oluşturulur?
- Immutable veriler kullanmanın faydaları
Primitive ve Reference Tipler
Primitive tipi değerler sabittir ve stack'te tutulurlar. Bu tiplere erişim direkt değerleri ile gerçekleşir. Javascript geliştirirken en sık kullandığımız değerler. Primitive tipi değerler şunlardır:
- undefined
- null
- boolean
- number
- string
- symbol
Reference tipi değerler heap'te tutulurlar ve erişim memory'deki referans adresleri ile gerçekleşir. Reference tipi değerler şunlardır:
- object
⚠️ Javascript'te fonksiyonlar ve diziler da birer objedir. Bu yüzden listeye eklemedim.
Tüm bunları javascript'te değişmezlik konusuna girizgah olması için anlattım 😄.
Mutability ve Immutability Nedir?
Bu iki kavram programın akışı içinde oluşturulan bir verinin değişip değişmemesine yönelik kavramlardır. Yazılım geliştirirken herhangi bir veri üzerinde değişiklik yaparken orijinal verinin korunmasını isteriz. Çünkü orijinal veriyi birden fazla yer kullanıyor olabilir. Değeri korunmayan bir veride yapılan değişiklik program akışında beklenmedik yerleri etkileyebilir bu da kodun debug edilmesini zorlaştırır ve öngörülebilirliği azaltır.
Primitive tipi değerler memory'de değerleri ile saklandıkları için akış boyunca korunurlar. Immutable yani değişmez değerlerdir. Reference tipi değerler ise memory'de referans adresleri ile saklandıkları için akış boyunca korunma garantileri yoktur. Mutable yani değişebilir değerlerdir.
Kod üzerinde izah etmeye çalışayım.
let userName = 'John'
let adminName = userName
adminName = 'David'
console.log(userName) // 'John'
console.log(adminName) // 'David'
userName
değişkenini adminName
değişkenine atadık ve adminName
değişkeninin değerini program akışının herhangi bir yerinde güncelledik. Bu işlemde userName
değişkenin değeri adminName
değişkenine birebir aktarılmış oldu ve sonuç olarak hem userName
hem de adminName
değişkenleri için memory'de yer ayrıldı. Her biri için memory'de farklı yerler ayrıldığı için program akışı içinde birbirlerinin değişimlerinden etkilenmeyecek ve değerleri korunacaktır.
Objelerin mutable yani program akışı boyunca değişebilen değerler olduğunu öğrenmiştik. Bunu kod üzerinde görmeye çalışalım.
let person = {
name: 'Robert Lewandowski',
height: 185,
weight: 79
}
let footballer = person
footballer.name = 'Wayne Rooney'
console.log(person.name) // 'Wayne Rooney'
console.log(footballer.name) // 'Wayne Rooney'
Immutable örneğinde yaptığımız işlemlerin aynısını yaptık. Fakat farklı sonuçlar aldık. Çünkü person
değişkenin referans adresi ile footballer
değişkeninin referans adresi aynı. person
değişkeni herhangi bir değişkene aktarılmak istendiğinde değerleri kopyalanmaz referans adresi kopyalanır. Haliyle aktarılan tüm değişkenler akış içindeki güncellemelerden etkilenirler.
Dizilerin değişebilirliği ile ilgili bir örnek yapalım.
let fruits = ['mango', 'kiwi', 'pineapple']
let tropicalFruits = fruits
tropicalFruits.push('papaya')
console.log(fruits) // ['mango', 'kiwi', 'pineapple']
console.log(tropicalFruits) // ['mango', 'kiwi', 'pineapple', 'papaya']
Örneklerle mutable ve immutable kavramlarını basitçe incelemiş olduk. Peki dizilerde ve objelerde değişmezliği nasıl sağlayacağız 🧐?
Dizilerde ve Objelerde Immutability
Dizilerde ve objelerde değişmezliği sağlamanın birden fazla yolu vardır. Hem bu amaca hizmet eden kütüphanelerle hem de javascript'e yeni gelen özelliklerle immutability'i sağlamak mümkün. immutable.js bu soruna çözüm bulan ve fazlasıyla popüler bir kütüphanedir. Fakat syntax'ı hoşuma gitmediği pek önermiyorum. Daha çok spread (...)
operatörü ve Object.assing()
metodunu kullanıyorum ve size de bunları kullanmanızı tavsiye ederim. Yukarıda yaptığımız örnekleri bu iki yöntemle güncellemeye çalışalım.
⚠️ Yazının amacından şaşmaması ve gereksiz uzun olmaması için bu operatör ve yöntemin nasıl kullanıldığını açıklamayacağım.
// spread (...) operatörü yöntemi
let person = {
name: 'Robert Lewandowski',
height: 185,
weight: 79
}
let footballer = {
...person,
name: 'Wayne Rooney'
}
console.log(person.name) // 'Robert Lewandowski'
console.log(footballer.name) // 'Wayne Rooney'
// Object.assign() yöntemi
let person = {
name: 'Robert Lewandowski',
height: 185,
weight: 79
}
let footballer = Object.assign({ name: 'Wayne Rooney' }, person)
console.log(person.name) // 'Robert Lewandowski'
console.log(footballer.name) // 'Wayne Rooney'
// spread (...) operatörü yöntemi
let fruits = ['mango', 'kiwi', 'pineapple']
let tropicalFruits = [...fruits, 'papaya']
console.log(fruits) // ['mango', 'kiwi', 'pineapple']
console.log(tropicalFruits) // ['mango', 'kiwi', 'pineapple', 'papaya']
Gerçek Hayattan Bir Örnek
Yukarıda yaptığımız örnekler gerçek hayatta yaptığımız geliştirmelerden biraz uzak. Bu nedenle tarihlerle haşir neşir olanlarınızın bileceği moment.js kütüphanesiyle bulunduğumuz tarihten bir gün ve iki gün sonrasının hangi günlere denk geldiği gösteren ufak bir örnek yapalım.
import moment from 'moment'
moment.locale('tr')
const now = moment()
const today = now
const oneDayLater = today.add(1, 'days')
const twoDaysLater = oneDayLater.add(1, 'days')
document.write(
`
<p>Bugün: ${today.format('dddd')}</p>
<p>Yarın: ${oneDayLater.format('dddd')}</p>
<p>Ertesi Gün: ${twoDaysLater.format('dddd')}</p>
`
)
Yaptığımız örneğin çıktısına baktığımızda sorunu rahatça anlayabiliyoruz. Günler için oluşturduğumuz değişkenlerin hepsi now
değişkeninin referans adresini kullanıyor. Bu yüzden yaptığımız her güncelleme zincirleme olarak now
değişkenin değerini değiştiriyor.
Yaptığımız uygulamaya aiağıdan göz atabilirsiniz 😇.
Yorumlar
Soru, cevap ve destekleriniz için aşağıdan yorum bırakmayı unutmayın.