Mutable & Immutable !

October 12, 2020

Bu yazımda mutable ve immutable terimleri üzerinde durucam. Nedir bu mutable ve immutable terimleri ?

Immutability bir verinin asla değişmemesi anlamına gelmektedir. Veri üzerinde bir değişiklik yapıldığında orjinal veri her zaman korunur. Eğer orjinal veri korunmuyorsa bu mutable dır.

Eminim ES6 ile gelen const tanımı ile verilerimizi immutability yapabileceğimizi düşünmüşsünüzdür. Ama const ile immutability veri oluşturulamaz. Çünkü const ile değişkene atanan nesne üzerinde değişiklik yapılabilir.

const x = { name: "özgün", surname: "özdemir" };
x.name = "yazılımcı"

Yukarıda gördüğümüz gibi const ile oluşturduğumuz x objesinin name alanını yazılımcı olarak sonradan değiştirdik. Eğer x değişkenini console yazdırarak tekrardan bakarsanız name alanını yazılımcı olarak görürsünüz. Bu örnek bize const ile immutability veri tipi oluşturamadığımızı net bir şekilde gösteriyor.

Reference ve Primitive Değerler

Javascripte veri tipleri 2 kategoriye ayrılır. Bunlar non-primitive (Reference) ve ilkel (Primitive) veri tipleri olarak adlandırılır. Non primitive veri tipleri değişkenin referansını yani adresini tutar. İlkel veri tipleri ise değişkenin direk değerini tutar.

İlkel (Primitive) veri tipleri immutable, non-primitive (Reference) veri tipleri ise mutable dır

Javascripte değişkenlere atadığımız değerler bellekte saklanır. Bellek alanları Stack ve Heap dir.

Heap : Değişkenleri tanımladığımız zaman nesnelerin depolandığı yerdir. Aslında nesneler ( object ) ve diziler ( array ) burada depolanır. Heap alanında depolanan bu veriler için stack alanında gösterge ( pointer ) saklanır.

Stack : Stack genellikle düşük maliyetli veriler için kullanılır. Örneğin integer, float, string vs

Non-primitive (Reference) veri tipleri program yazarken başımıza belli sorunlar açabilmektedir. O yüzden mantığı çok güzel bir şekilde kavrayıp ona göre hareket etmemiz gerekiyor

Örneğin;

let person = { name: "Özgün" };
let cousin = person;
person.name = "Sarp";

console.log(person); // { name: "Sarp" }
console.log(cousin);  // { name: "Sarp" }

Yukarıdaki örnekte gördüğümüz gibi person objesinin name alanını değiştirdiğimizde cousin objesininde name alanı değişiyor. Orjinal veriyi bu şekilde koruyamadığımızı görebiliyoruz. Çünkü person nesnesinin yeri heap alanında pointer ( gösterge ) stack alanında tutulmaktadır

Elimizde bir object olduğunu düşünelim. Program akışı gereği object üzerinde değişiklik yapmamız gerekiyor ama orjinal verininde korunmasını istiyoruz. Peki bunu nasıl başarıcaz ? Çözüm yolları nelerdir ?

Çözüm

Object Spread :

let person = { name: "Özgün" };
let cousin = { ...person };

Object Assign :

let person = { name: "Özgün" };
let cousin = Object.assign({}, person);

Slice :

let person = { name: "Özgün" };
let cousin = person.slice();

Yukarıdaki 3 yöntemde de birinci seviye kopyalama sağlanmaktadır. Yani nesne içerisinde nesneler bulunuyorsa yine orjinal verinin korunamaması gibi sorunlar ile karşılaşabilmekteyiz.

Bu sorunu da aşağıdaki yöntem ile çözebiliriz. Bu şekilde derin kopyalama yapabiliriz.

let person = { name: "Özgün" };
let cousin = JSON.parse(JSON.stringify(person));
Share: