JavaScript Coercion

Coercion ya da Türkçe karşılığı ile “zorlama” dinamik programlama dillerinde değerlerin bir tipten diğer bir tipe dönüştürülme yöntemlerinin bütünüdür. C++, Java, C# gibi tüm dillerde bir tip dönüşümü yapısı bulunmaktadır. JavaScript’de de bu yapı bulunmaktadır. Bunu iki farklı başlık altında inceleyebiliriz. Açık ve üstü kapalı zorlama. Açık zorlamanın iyi, üstü kapalı zorlamanın ise kötü olduğu söylenir fakat neyi ne zaman kullanacağınızı bilirseniz her ikisinin de faydalı tarafları vardır.

Yazının devamında bahsedeceğim dönüşümleri takip etmek için bu linki kullanabilirsiniz.

Açık (Explicit) Zorlama

Adından da anlaşılacağı gibi kodda açıkça yaptığınız zorlamalardır. Bir koda baktığınızda bir tipten diğer tipe yapılan dönüşüm açıkça anlaşılmalıdır. Derleme zamanında değil de çalışma zamanında gerçekleşirler. Aşağıdaki örnekte string tipinden number tipine ve tersine dönüşümleri göstermeye çalıştım.

Görüleceği üzere bunun birkaç yolu var. Bunlardan biri de parseInt() fonksiyonu kullanmak. Bu fonksiyon soldan sağa karakterleri gezerken karakteri 0'dan 9'a olan sayıya dönüştürüp dönüştüremeyeceğine bakar ve dönüştürebiliyorsa bir sonraki karaktere geçer. Ama karşısına dönüştüremeyeceği bir karakter çıkarsa orada durdurur ve o ana kadar dönüştürdüklerini döndürür. Yani parseInt() fonksiyonuna 123px değerini verirseniz bu size 123 olarak geri dönecektir.

Bir diğer yöntem olanNumber fonksiyonu da string number dönüşümü yapar fakat parseInt() fonksiyonundan farklı olarak aldığı değerlerin tüm karakterlerinin bir sayıya dönüşmesini bekler. Biri bile sayı dönüşmezse NaN (Not a Number) değeri döndürecektir.

8. satırda gördüğümüz + operatörü de Number fonksiyonu ile birebir aynı işi yapmaktadır.

Bir çok kişi Javascript’de her şey nesnedir yanlış düşüncesi içindedir. Çünkü ilkel bir değerin fonksiyonunu çağırıyoruz ve ilkel bir değerin fonksiyonu olmaz nesnelerin fonksiyonları olur. Peki nasıl oluyor da toString() fonksiyonunu çağırıyoruz. İşte tam burada JavaScript devreye giriyor sizin için otomatik olarak ilkel bir tipten nesneye dönüşüm yapıyor ve fonksiyonu çağırmanıza yardımcı oluyor. İşte bu sebepten 12. satır için üstü kapalı açık diyebiliriz.

15. satır için ise açıkça açık coercion diyebiliriz.

Bu yöntemlerden hangisini kullanacağınıza takımınızla beraber karar vererek bir biçim rehberi yayınlamanızda fayda görüyorum. Örnek bir biçim rehberi için buraya bakabilirsiniz. Ben bu yöntemlerden Number() ve String() fonksiyonlarını kullanmayı tercih ediyorum. Çünkü tanım gereği ne yapmak istediğiniz açık olmalı ve bu iki yöntem ne yapmak istediğinizi açıkça ifade ediyor.

Peki boolean tipindeki değişkenler için nasıl oluyor. Üstteki örneği incelersek number ve string tiplerinde olduğu gibi boolean tipi için de Boolean() fonksiyonu ile dönüşüm işlemini açık bir şekilde gerçekleştirebiliyoruz.

5. satırda neler olduğuna bakalım. Bir çok işi !! operatörünün, zorlama işlemi için özel bir işlemci olduğunu düşünür fakat öyle değildir. Burada iki farklı işlem söz konusudur. Birisi a değişkenini boolean için zorlar ve sonucu aksine çevirir fakat bu istemediğimiz bir sonuçtur ve diğeri ise aksine çevrilmiş sonucu tekrar tersine çevirerek istenen sonucu üretmiş olur. Mülakatlarda karşınıza çıkabilecek türden bir dönüşümdür.

Üstü Kapalı Zorlama

Üstü kapalı zorlama yapmak istediğiniz dönüşümü kapalı olarak yapmaktır. Sonucunun anlaşılması zor olan kodlardır. Sol kulağınızı sağ elinizle ensenizin arkasından tutmaya çalışmaktır.

- , / , * operatorleri matematiksel operatorlar oldukları için işleme giren değerleri sayı olmaya zorlarlar. Böylece işlemin sonucu da size number tipinde döner. Fakat + operatoru aşırı yüklenmiştir. İşleme girenlerden biri string bir değerse ikisini de string yapmaya zorlar ve string birleştirme işlemi gerçekleştirir.

Boolean tip üzerinde üstü kapalı zorlamaları üstteki örnek ile inceleyelim.

2. satırda kullanılan if ben de dahil birçok geliştirici tarafından kulanılmaktadır ve faydalı bir kullanımdır. Genellikle bunu, değişkende bir değer olup olmadığını test etmek için kullanırız.

6. satır if koşuluna girmeyerek 9. satıra geçecektir. Çünkü 0 zorlama ile false değerine dönüşmektedir.

9. satırda ise == ile kıyaslama yapılmaktadır. == ile kıyaslama yapıldığında bu operator sayıları kıyaslamayı öncelikler. Dolayısıyla false değerini önce sayıya çevirir bunun da karşılığı 0'dır ve sonuçta 0 0'a eşit olduğundan koşulu sağlar ve bloğun içine girer. Bu çalışma prensibi mülakatta sorulacak cinstendir. Her iki tarafın da boolean olduğundan emin değilseniz hatta eminseniz bile == kontrolünü true ve false değerleriyle beraber kullanmayın.

12. satır belki de en faydalı üstü kapalı zorlamadır. Buradaki || operatorü mantıksal bir operator değil seçim operatoru olarak kullanılmaktadır. İlk işleme giren değer doğru ise onu, yanlış ise diğerini seçmek için kullanılmaktadır. Bu sebeple 13. satırda foo yazdığını görürsünüz. Bu kullanımı && operatoründe de görebilirsiniz. func && func() şeklinde kullanılan && operatoru önce func fonksiyonun varlığını kontrol eder sonra çalıştırır. Yoksa kısa devre olur ve hiç çalıştırmayı denemez.

Üstteki kod parçasındaki 2. satırda bir önceki örnekte olduğu gibi == sayısal karşılaştırma yapacağından true önce sayıya çevrilir 123 değeri de yine sayıya çevrilir ve kıyaslanır bu sebeple if bloğuna girmeyecektir.

7. satırda isea değişkenindeki dizi boş stringe boş string de sayıya dönüştürülür ve sonucunda 0 elde edilir. Bu sebeple buradaki if bloğuna da girmeyecektir.

10. satırda da array 0'a dönüşür false da 0'a dönüşür ve if bloğuna girer. İşte tam da bu sebepten == ile true ve false değerlerini kıyaslamamayı öneriyorum.

Bazı ilginç kıyaslamalar. “” == 0 , “” == [], 0 == [], [] == ![] bunların tamamının değerinin true olduğu görülüyor. Tuhaf!

Çift Eşittir (==) vs Üç Eşittir (===)

Genel olarak ikisi arasındaki fark şöyle bilinir. == değerleri kontrol eder === ise hem değerleri hem de tipini kontrol eder. Bu yanlıştır.

Kaynak: https://www.ecma-international.org/ecma-262/8.0/#sec-abstract-equality-comparison

== zorlamaya izin verirken === ise izin vermez. Hangisini kullanacağınıza bunu düşünerek karar verin.

Aşağıda yapmamanız gereken karşılaştırmalar yer alıyor.

Tamamiyle == karşılaştırmasından kaçınmamak da gerekir. Peki ne zaman faydalı olur. Aşağıdaki kod parçacığını düşünelim.

Kullanımınızda veri tipi önemli değilse daha okunabilir kod yazmak için == kullanılabilir.

Bir başka örnek de değer atanmamış veya null atanmış değişkenlerin değerini kontrol etmek için == kullanarak kodu daha okunabilir yapabilirsiniz.