JavaScript ES6+ İpuçları #3: Record ve Tuple ile Native Değişmezlik Sağlamak

Tuğsan Ünlü
5 min readAug 12, 2020

--

JavaScript Record

JavaScript ES6+ serisindeki bir önceki yazı: JavaScript ES6+ İpuçları #2: Optional Chaining Operatörü ile Pratik Zincirleme

JavaScript’de değişmezlik, veri tiplerine göre farklı şekillerde ele alınan bir konu. Ben bu yazıda değişmezliğin ne olduğuna ve JavaScript’de şimdiye kadar nasıl uygulandığına çok kısa değindikten sonra yakın vadede hayatımıza girmesi muhtemel olan yeni bir değişmezlik sağlama yönteminden bahsedeceğim. Değişmezlik konusunun detaylarını merak edenlere ise Oğuz Kılıç’ın çok beğendiğim JavaScript’de Değişmezlik isimli blog yazısını öneriyorum.

const

Yazdığımız uygulamalar içerisindeki mantıksal akışlarda kimi verilerin değişmemesini, yeniden üzerine yazılabilir durumda olmamasını isteyebiliyoruz. JavaScript’de ES6 ile birlikte hayatımıza giren const anahtar kelimesiyle tanımladığımız sabitlerde bunu kısmen sağlayabiliyoruz. Bununla ilgili hızlıca iki örnek vereceğim.

İlkel bir veri tipinde const kullanımı
Referans bir veri tipinde const kullanımı

Örneklerde görüldüğü gibi const anahtar kelimesiyle oluşturduğumuz ilkel (primitive) bir veri tipine sahip sabiti değiştirmek istediğimizde bu işlemi yapamayacağımıza dair hata (type error) alıyoruz. Fakat benzer bir işlemi referans (non-primitive) veri tipine sahip bir sabit üzerinde yapmak istediğimizde atama işlemini sorunsuz bir şekilde yapabiliyoruz.

Özetle const, ilkel tipler için ilgili sabite yeniden atamayı engelleyerek değişmezlik sağlarken nesne ve dizi gibi referans tipler için etkisiz kalıyor. Bu veri tipleri için değişmezlik sağlamanın alternatif yöntemleri var. Fakat bu yöntemler performans ve kullanım kolaylığı açısından geliştiricileri üçüncü parti çözümler kullanmaya itiyor. Hemen bununla ilgili bir örnek daha vereceğim.

Object.freeze()

Object.freeze() nesne ve dizileri kelimenin tam manasıyla dondurmaya yarayan bir metot. Bu sayede tıpkı const ile ilkel tiplerde sağlanan değişmezliğe benzer şekilde bir değişmezlik referans tipler için de sağlanabiliyor.

Object.freeze() ile nesne dondurma

Fakat kullanımıyla alakalı birkaç handikap var. Bunlardan ilki Strict mode haricinde hata fırlatmaması. Üstteki örnekte de görüleceği üzere dondurduğum nesnenin özelliğini değiştirmek istedim. Metot bu işlemi yapamamasına rağmen ilk örnekteki gibi bir tip hatası fırlatmadı. Aksine atama teşebbüsüm sonucunda değiştirmek istediğim metni döndürerek atama işlemini yapabilmiş gibi davrandı. Bu epey kafa karıştırıcı bir kullanım örneği.

Bir diğer handikapı da dondurma işlemini yalnızca nesne veya dizi içerisindeki ilkel tipler için yapabiliyor olması. Derinlemesine (deep) değil sığ (shallow) bir şekilde değişmezlik sağladığı için aşağıdaki gibi veri yapısında değişmesini istemediğimiz özellik günün sonunda değişmiş olacak.

Object.freeze() ile derinlemesine değişmezlik örneği

Record & Tuple ile Native Değişmezlik

Record ve Tuple, referans tiplerdeki bu değişmezlik sorununu çözmeyi amaçlayan çok yeni bir JavaScript özelliği. Henüz TC39 öneri sürecinde 2. adımda bulunuyor. Yani taslak aşamasında. Fakat şu hâliyle bile hem geliştiriciler hem de komite tarafından oldukça ilgi görüyor. Hatta ES6 sınıflara gizli alanlar tanımlayarak kapsülleme yapmaya imkân sağlayan Class Fields ile birlikte son zamanların en çok konuşulan önerilerinden olduğunu söylesem abartmış olmam sanıyorum. GitHub’daki yıldız sayıları ve depolardaki hareketlilikler de bunu doğrular nitelikte.

Record ve Tuple, çok yeni bir öneri sayılmaz aslında. Düşünülen ekstra özelliklerle 2015 senesinde konuşulmaya başlanan bir çözümün izinden gidiyor. Kullanımı ise oldukça basit. Bir nesne veya diziyi tanımlarken başına koyulacak bir işaretçi (#) ile değişmez olup olmayacağının belirtilmesi gerekiyor. Bu işaretçi nesne söz dizimiyle birlikte kullanıldığında oluşan yapıya Record, dizi söz dizimiyle birlikte kullanıldığında ise Tuple deniyor. Hemen bir örnek yapalım.

JavaScript record kullanımı

Yukarıdaki örneklerin aksine, tanımladığımız referans bir veri tipine sahip sabit nesnenin özelliğini değiştirmek istediğimizde ilgili özelliğin yalnızca okunabilir olduğu uyarısını alıyoruz ve orijinal nesnemiz üzerinde bir değişiklik olmadığını görüyoruz.

JavaScript Tuple kullanımı

Tuple kullanımı da aynı şekilde ilgili dizi içerisindeki herhangi bir değeri değiştirebilmemizi engelliyor.

Record ve Tuple’ın en güzel özelliklerinden birisi varsayılan olarak derinlemesine (deep) değişmezlik sağlaması. Yani yukarıdaki Object.freeze örneğindeki gibi kimi veri tiplerini değiştirilebilir kimi veri tiplerini değiştirilemez olarak bırakmıyor. Sağladığı bu bütünlüklü kullanım Object.freeze() gibi alternatif yöntemler kullanırken oluşan kafa karışıklarının önüne geçecek gibi duruyor.

Record içerisinde ilkel tiplerde değişmezlik

Ayrıca Record ve Tuple’lar içerisinde değiştirilebilir bir nesne veya dizi kullanılmasına henüz tanımlama aşamasında izin verilmiyor. Record ve Tuple’lar içerisinde ilkel veri tiplerini ve yine başka Record ve Tuple’ları barındırabiliyor. Bu sayede tam anlamıyla bir değişmezlik sağlanmış oluyor.

Record içerisinde dizi ve Tuple kullanımı

Taslak aşamasındaki bir özellik olduğu için Record ve Tuple’ları web tarayıcılarının JavaScript motorları henüz doğrudan anlayamıyor. O yüzden deneyimleyebilmek için özelliğin geliştiricilerinden Rick Button’un oluşturduğu oyun alanı kullanılabilir. Ben de bu yazıdaki örneklerimi orada hazırladım. Alternatif olarak Babel’a Stage 2 özellikleri ve @babel/plugin-syntax-record-and-tuple eklentisi dahil edilerek deneyimlenebilir.

Record ve Tuple JavaScript ekosistemi içerisindeki önemli eksiklerden birisini kapatacak. Arkasındaki destekle tahmin ediyorum ki öneri adımlarını hızla geçecek ve yakın vadede projelerimiz içerisine dahil etmeye başlayacağımız bir özellik olacak. Daha önce Nullish ve Optional Chaining Operator gibi bir yandan dilin eksiklerini görüp gideren bir yandan da daha okunabilir bir şekilde JavaScript yazmamızı sağlayan ES6+ özelliklerinden bahsetmiştim. Record ve Tuple o yazıların üçüncüsü oldu. Gözüme kestirdiğim birkaç TC39 önerisi daha var. Fırsat buldukça onları da yazacağım.

Aşağıdaki kaynaklar arasında birkaç tane okuma önerisi ekliyorum. Favorim özellikle Record ve Tuple’larla eşitlik karşılaştırma örnekleri. JavaScript camiasında çok su kaldıran bir konu eşitlik. Record ve Tuple kullanımıyla birlikte o konuya da farklı bir açıdan bakmak gerekecek.

Kaynaklar

JavaScript ES6+ serisindeki bir sonraki yazı: JavaScript ES6+ İpuçları #4: Pipeline Operatörü ile Çıktıları Yönlendirmek

--

--

Tuğsan Ünlü
Tuğsan Ünlü

Written by Tuğsan Ünlü

Senior Application Architect, Technical Product Owner @Akbank — tugsanunlu.com

No responses yet