Opsiyonel Zincirleme Operatörü, Aslında C# geliştiricileri arasında C# 6 ile beraber gelen “Null Propagation” operatörünü bilenler ve kullananlar bu makalenin konusu olan Optional Chaining için yabancılık çekmeyeceklerdir ayrıca popüler diğer yazılım dillerin çoğunda da bu özellik yer almaktadır ve artık Javascript’de Optional Chaining operatörünü kullandığımız sürece kolay kolay “Uncaught TypeError ” almayacağız.
Javascript “Opsiyonel Zincirleme – Optional Chaining” Operatörü Nedir?
Türkçe çevirisi opsiyonel zincirleme, isteğe bağlı zincirleme olarak çıkan bu özelliği biz optional chaining olarak bilsek bize yeter adından ziyade işlevine odaklanabiliriz 🙂 Şunu özellikle belirteyim bu özellik standart olarak bir javascript özelliği değildir. Javascript compiler’larından birini kullanarak bu özelliği kullanabilirsiniz ama her compiler bu özelliği desteklememektedir babel javascript compiler’ında şuan bu özellik mevcut. Umarım en kısa sürede diğer compiler’lara kazandırılır yada kökten çözüm olarak umarım en kısa sürede javascript standart’ı olarak kodlarımız arasında yer bulur.
Typescript üzerinden javascript kodlaması yapan biri olarak typescript’de bu özellik şuan(13.01.2019) en güncel sürüm olan Typescript 3.2 versiyonunda halen implement edilmemiş olduğundan kullanamıyorum ama oldukça beğendiğim bir özellik peki “Uncaught TypeError”den kurtulmak için ne tür yöntemler kullanıyorduk o yöntemlere gözatalım.
Senaryomuzda kullanacağımız dummy data alttaki gibidir bu data üzerinden doğal yollardan güvenli olarak alt objelere exception fırlatılmadan nasıl gidebileceğimize gözatalım.
1 2 3 4 5 6 7 8 9 | const result = { name: "Murat ÖNER", office: { primary: { city: "İstanbul", state: "TR" } } } |
Eğer üstteki datayı bir apiden çekiyorsak ve api her zaman üstteki gibi bir sonuç veriyor alt objeleri sıkıntısız dolu getireceğine eminseniz javascript tarafında alttaki gibi en alt değerlerden biri olan city özelliğinin değerine erişebilirsiniz.
1 2 | const city = result.office.primary.city; // --> "İstanbul" |
Ama olduki office yada primary objesi dolu gelmedi ve sizde bu objelere dolu geleceğine güvenip veri doğrulama kontrolü yapmadınız sonuç! 💥😱 👇
Peki üstteki görselde ifade edildiği gibi patlamamak için nasıl ve hangi yolları kullanabiliriz en sağlıklı ve temiz yol hangisidir bunlara adım adım değinelim.
Yeni bir kullanıcı kaydına eriştik bu kaydın office objesi yok peki ne olacak görelim.
1 2 3 | const result = { name: "Murat ÖNER" } |
1 2 | const city = result.office.primary.city; // --> Uncaught TypeError: Cannot read property 'primary' of null |
Bir önceki json verisi üzerinden eriştiğimiz gibi aynı özelliğe erişmeye çalıştığımızda görüldüğü üzere Uncaught TypeError: Cannot read property 'primary' of null
hatasını alıyoruz. Hadi o zaman bir tülü geçemediğimiz şu adımları ciddi ciddi geçelim 🙂
İçiçe if blokları
1 2 3 4 5 6 7 8 9 10 11 | let city: string | undefined = undefined; if (result) { const office = result.office; if (office) { const primary = office.primary; if (primary) { city = primary.city; } } } document.write(city) // İstanbul |
Açıkçası sırf bir objeye erişim için bu kadar boğuşmaya değermi bilmiyorum ama bu nesne kırılım sayısının buradaki gibi 3 değilde 5-10 yada daha fazla olduğunu varsayarsak bir noktadan sonra kod okunulmaz hale gelecektir o zaman bunu beğenmediğinizi düşünerek bir sonraki yönteme geçelim.
Mantıksal İfadeler
1 2 3 4 5 6 | var city = result && result.office && result.office.primary && result.office.primary.city document.write(city) // İstanbul |
Üstteki mantıksal “&&” ifadesi ile her defasında bir kırılım aşağı inip değerin varolup olmadığını kontrol ederek ilerlediğimizde “İstanbul” değerine ulaşacağız ve kırılımlardan biri olmadığından yada result adındaki nesnenin direkt kendisi olmadığında herhangi bir problem yaşatmayacak ve undefined dönecek fakat yinede uzun bir yöntem helede kırılım sayısının daha yüksek olduğunu düşünürsek okunaksız kodlarımız olmuş olur.
Ternary Operatörler
Genelde kısa if-else operatörü olarak da bilinen bu operatör yardımı ile nasıl sonuca ulaşacağımızı alttaki kodlardan görebilirsiniz.
1 2 3 4 5 6 7 8 9 10 11 12 13 | var city = !result ? undefined : !result.office ? undefined : !result.office ? undefined : !result.office.primary ? undefined : !result.office.primary.city ? undefined : result.office.primary.city document.write(city) // İstanbul |
Try-Catch
Try blokları arasında alttaki gibi ilgili nesneye erişip eğer makalenin başında aldığımız Uncaught TypeError: Ca...
hatayı yada farklı bir hata alırsak catch bloğu içerisinde try-catch blokları dışına tanımladığımız city değişkenine null değeri atayıp bu şekilde bir takla ile sonuca ulaşmış oluyoruz.
1 2 3 4 5 6 7 8 9 | var city try { city = result.office.primary.city } catch(error) { city = null } document.write(city) |
Heryerde bunun gibi kırılımlara sahip özelliklere ve değerlerine erişmek istediğimizde bu yöntemleri kullanırsak kod okunaklığı açısından çok kötü seçimler yapmış olacağız ki şimdiye kadar yaptık bunu en minimum seviyeye getirmek için çeşit yöntemler kullandık bu yöntemlerden biride özellik seçim kütüphaneleridir ve bu kütüphanelerden bazıları lodash, ramda kütüphaneleridir. Örnek olarak üstteki result nesnesi üzerinden giderek lodash kütüphanesi üzerinden nasıl city değerine tek satırda güvenle ulaşabileceğimizi görelim.
lodash
1 2 | import * as _ from 'lodash'; var city = _.get(result, 'office.primary.city', undefined); |
Üstteki kodu basitçe açıklarsan
lodash
kütüphanesini “_” karakterinden erişecek şekilde import ettik veget
fonksiyonunu kullandık sırasıyla özelliğine erişmeye çalıştığımız asıl nesneyi geçtik sonrasında hangi kırılımlar altındaki hangi özelliğe erişecek isek sırasıyla girdik ve son parametreye de eğer belirttiğim özelliğe erişemez ise varsayılan olarak döndereceği değeri girdik. Üstteki kodu çalıştırdığımızca İstanbul sonucu dönecek fakat eğercity
özelliğini yada üst kırılımlardan birini bulamasaydıundefined
sonucu dönecekti. Ama erişmek istediğimiz özellik ve kırılımları string olarak yazmak bence çok sağlıklı olmamakla beraber Optional Chaining özelliğinin olmadığı durumda kullanabileceğiniz en iyi seçenek gibi duruyor.
Peki hiçbir kütüphaneye ihtiyaç duymadan makale konusu olan Optional Chaining özelliği nasıl kullanacağız?
Aslında hiçbir kütüphaneye ihtiyaç duymadan diyemeyiz çünkü her ne kadar makale girişinde babel üzerinden bu özelliği kullanabileceğimizi söylesek de @babel/plugin-proposal-optional-chaining adındaki plugin’i babel’e dahil ederek kullanabilirsiniz. Bu plugin’i babel’e dahil ettikten sonra alttaki gibi kolayca okunabilir ve anlaşılabilir en iyi sözdizimi ile javascript kodlaması yapabileceksiniz.
Babel – Optional Chaining Operatörü
1 | const city = result?.office?.primary?.city |
Gördüğünüz gibi typesafe, okunabilir, yönetilebilir, güvenli kod standartlarına uygun sözdizimi ile city nesnesine erişebildik.
Özetle
Eğer backend ile de ilgileniyorsanız birçok programlama dilinde Optional Chaining farklı isimlendirmelerde de olsa yer almaktadır örnek olarak en sık kullandığım programlama dillerinden biri olan C#’da bu özelliği C# 6 ile beraber zaten kullanıyoruz ve oldukça kullanışlı bir özellik olduğu belirtmem gerekiyor. Üstteki kötü javascript örnek kodlarında olduğu gibi birçok if bloklarından bizi kurtarıyor ve okunabilir kodlar yazmamıza izin vermiş oluyor. Eğer herhangi bir Javascript compiler’ı kullanmıyorsanız şimdiden Typescript, Babel gibi compiler’lardan birini seçmenizi şiddetle tavsiye ederim(Dikkat! Bağımlılık yapabilir). Şuan özellikle Typescript tarafına da gelmesini bekliyorum, umarım en kısa sürede gelir ve umarım en kısa sürede javascript standart’ı olarak da bu özellik kazandırılır.
📚 Diğer Javascript Makaleleri
- Javascript notification api kullanımı
- Javascript de fetch fonksiyonu ile http işlemleri
- Javascript de class tanımlama ve diğer class işlemleri
- Javascript ile forEach döngüsü kullanımı
📚 Kaynaklar
- https://blog.benestudio.co/optional-chaining-operator-in-javascript-342082de2db
- https://www.bram.us/2017/01/30/javascript-null-propagation-operator/
- https://dev.to/sammyisa/optional-chaining-may-be-coming-to-javascript–4ff0
✍ Lütfen olumlu-olumsuz tüm görüşlerinizi bana yorum yada mail yolu ile iletmeyi ihmal etmeyin.
🔗 Sosyal medya kanallarından makaleyi paylaşarak destek olursanız çok sevinirim.
👋 Bir sonraki makalede görüşmek dileğiyle.
Yeni başlayan birisi olarak çok faydalı buldum
Verdiğiniz örnekler gayet iyi diğer dillerden bahsetmeniz de çok hoş olmuş
Teşekkürler