Menu

JavaScript Tip Dönüşümü: Implicit vs Explicit

JavaScript değerleri tipler arasında nasıl dönüştürür? Kafa karıştıran implicit kuralları, tercih etmeniz gereken explicit dönüşümleri ve hangisinin ne zaman devreye girdiğini inceliyoruz.

İki Tür Tip Dönüşümü

JavaScript tipler konusunda oldukça esnektir. Bir operatör "yanlış" tipte bir değer aldığında dil hata fırlatmaz; değeri dönüştürür. İşte bu dönüşüme tip dönüşümü (coercion) deniyor ve iki şekilde karşımıza çıkıyor:

  • Açık (explicit) tip dönüşümü — siz talep edersiniz: Number("42"), String(99), Boolean(value).
  • Örtük (implicit) tip dönüşümü — siz bir dönüşüm yazmadan, operatörün kendisi tetikler: "5" - 2, "" == 0, if (value).

İkisi de sonuçta aynı dönüşüm kurallarını çalıştırır. Tek fark, dönüşüme sizin mi yoksa dilin mi karar verdiği. JavaScript'te kafa karıştıran sonuçların neredeyse tamamı — "5" + 1 === "51", [] == false, null == undefined — gafil avlayan örtük tip dönüşümünden kaynaklanır.

index.js
Output
Click Run to see the output here.

Zihinsel model şu: Number(...) veya String(...) yazdığında ne istediğini biliyorsundur. Yazmadığın zaman ise her operatörün ne yapacağına dair kendi fikri vardır — ve bug'lar işte tam da bu fikirlerin içinde yaşar.

Üç Hedef Tip

JavaScript tip dönüşümü her zaman üç primitif tipten birine doğru yapılır: string, number ya da boolean. (Bir de bigint var ama diğer tiplerden ona otomatik dönüşüm olmaz.) Kuralların geri kalanı, operatörün hangi hedefe nişan aldığına göre şekillenir.

index.js
Output
Click Run to see the output here.

String'e dönüşüm en hoşgörülü olanıdır — her değerin bir string karşılığı vardır. Ama dikkat: objeler "[object Object]" gibi hiç işe yaramayan bir şeye dönüşür. Bir objeyi string ile birleştirip loglarken ("user: " + user) istediğinizi neredeyse hiç göremezsiniz bu yüzden. Onun yerine JSON.stringify kullanın veya template literal içinde istediğiniz alanları tek tek yazın.

Number'a dönüşüm (javascript string to number)

Number'a dönüşüm çok daha katıdır. String'in gerçekten sayıya benzemesi gerekir, aksi halde karşınıza NaN çıkar:

index.js
Output
Click Run to see the output here.

Parantez içindeki sürprizler, ezberlemeye değer olanlar:

  • Boş string ve yalnızca boşluk içeren stringler NaN değil, 0 döner.
  • null değeri 0 olurken, undefined NaN döner.
  • Boş dizi 0 olur; tek elemanlı bir dizi o elemanı dönüştürür; birden fazla elemanı olan dizi ise NaN döner.

İçinde fazladan karakter bulunan bir stringten sayı ayıklamak istiyorsan, Number yerine parseInt veya parseFloat kullan:

index.js
Output
Click Run to see the output here.

parseInt çağırırken radix parametresini (10) her zaman vermeyi alışkanlık haline getirin. Aksi halde "0x" ile başlayan stringler hex olarak yorumlanır ve bu büyük ihtimalle kastettiğiniz şey değildir.

Boolean'a Tip Dönüşümü (Boolean Coercion)

Üç tip dönüşümü içinde en kolayı boolean coercion. Kısa bir liste değer false'a dönüşüyor; geri kalan her şey true.

JavaScript'teki falsy değerler şunlar:

  • false
  • 0, -0, 0n
  • "" (boş string)
  • null
  • undefined
  • NaN

Hepsi bu kadar. Bunların dışındaki her değer — "false", "0", [] ve {} dahil — truthy kabul edilir.

index.js
Output
Click Run to see the output here.

Boş dizi ve boş nesnenin sonucu, özellikle Python'dan gelenleri fena halde yakalar. Python'da boş koleksiyonlar falsy'dir; JavaScript'te ise truthy sayılırlar. "Bu dizi boş mu?" diye sormak istiyorsan, doğrudan arr.length === 0 kontrolü yapmalısın.

Boolean'a dönüşüm (boolean coercion), bir değerin boolean beklenen bir yerde kullanıldığı her durumda devreye girer: if (...), while (...), üçlü operatör ? : ve mantıksal operatörler &&, ||, !.

+ Operatörü Özel Bir Durumdur

Aritmetik operatörlerin çoğu, operandlarını sayıya zorlar. Ama + biraz farklı çalışır — taraflardan herhangi biri string ise + string birleştirme (concatenation) yapar. Aksi halde sayısal toplama işlemini gerçekleştirir.

index.js
Output
Click Run to see the output here.

Değerlendirme soldan sağa yapılır. 1 + 2 + "3" ifadesinde önce 1 + 2 = 3 hesaplanır, ardından 3 + "3" = "33" olur. Ama "1" + 2 + 3 en baştan string moduna girer ve öyle de kalır: önce "12", sonra "123".

İşte bu yüzden string'leri + ile birleştirmek tehlikelidir. Template literal'larda böyle bir dert yok:

index.js
Output
Click Run to see the output here.

Template literal, count + 1 ifadesini önce kendi başına sayısal olarak hesaplar, sonra sonucu yerine yerleştirir. Sürpriz bir tip dönüşümü yok.

Açık (Explicit) Dönüşümleri Tercih Edin

Bir değeri gerçekten dönüştürmeniz gerekiyorsa, bunu açıkça belirtin. Birkaç karakter fazladan yazarsınız ama kodu sonradan okuyacak kişi için hiçbir belirsizlik kalmaz:

index.js
Output
Click Run to see the output here.

Boolean'lar için de aynı şey geçerli. !!value çalışıyor ve sık kullanılıyor ama Boolean(value) ne yaptığını net bir şekilde anlatıyor:

index.js
Output
Click Run to see the output here.

Mantıklı bir kural şu: uygulama mantığında açık dönüşümleri tercih edin; +x, !!x gibi kısa biçimleri ise yalnızca kısalığın önem taşıdığı ve niyetin bağlamdan net anlaşıldığı yerlere saklayın.

== Operatörü Tip Dönüşümüne Fena Halde Yaslanır

Eşitlik operatörleri, JavaScript tip dönüşümünde (type coercion) en çok sürprizle karşılaşacağınız yerdir. == karşılaştırma yapmadan önce dönüşüm uygular; === ise uygulamaz.

index.js
Output
Click Run to see the output here.

Yukarıdaki her bir true, çoğu geliştiricinin ezbere sayamayacağı çok adımlı bir tip dönüşümü zincirinin sonucudur. İşte asıl sorun da bu — kazara çalışan kod, ileride kırılan koddur. Eşitlik kurallarının tamamına bir sonraki sayfada gireceğiz; şimdilik akılda kalması gereken şu: varsayılan olarak === kullanın ve == operatörüne yalnızca x == null deyimi için başvurun (bu ifade hem null hem de undefined değerlerini tek seferde yakalar).

Hepsini Bir Araya Getirelim

Tip dönüşümünün nerede işe yaradığını, nerede başınıza dert açtığını gösteren tam bir örnek:

index.js
Output
Click Run to see the output here.

İkinci çağrıya dikkat edin. Number("") size NaN değil, 0 döndürüyor — yani parsePrice("") çağrısı 0 sonucunu veriyor ve bu, fonksiyonu kullanan birinin muhtemelen beklediği davranış değil. Boş girdinin reddedilmesi gerekiyorsa, açık bir kontrol ekleyin:

index.js
Output
Click Run to see the output here.

Hangi değerlerin 0'a, hangilerinin NaN'e dönüştüğünü bilmek, ileride saatlerce süren sinsi hataların önüne geçmenizi sağlayan türden bir bilgidir.

Özetle Aklınızda Kalması Gerekenler

  • Tip dönüşümü; operatöre bağlı olarak değeri string, number veya boolean'a çevirir.
  • + operatörü bir string ile kullanıldığında birleştirme (concatenation) yapar; diğer tüm aritmetik operatörler değeri sayıya zorlar.
  • Falsy değerler sabit ve kısa bir listedir — ezberleyin. Geri kalan her şey truthy'dir, buna [] ve {} de dahil.
  • Number("") sonucu 0, Number([]) sonucu 0, Number(null) sonucu 0'dır — ama Number(undefined) sonucu NaN'dir. Bu detaylar gerçek projelerde bug olarak karşınıza çıkar.
  • Örtük (implicit) dönüşüm numaraları yerine Number(x), String(x), Boolean(x) gibi açık (explicit) dönüşümleri tercih edin. Gelecekteki siz bunun için teşekkür edecek.

Sırada: Eşitlik Operatörleri

Karşılaştırmalardaki tüm bu tip dönüşümü hikâyesi aslında == operatörünün içinde yaşar. Bir sonraki sayfada == ile === ve Object.is arasındaki farkları, == operatörünün hâlâ işe yaradığı o tek kullanım kalıbını ve linter'ların neden varsayılan olarak gevşek eşitliği işaretlediğini inceleyeceğiz.

Sıkça Sorulan Sorular

JavaScript'te type coercion nedir?

Type coercion, JavaScript'in bir değeri otomatik olarak başka bir tipe dönüştürmesidir — sayının string'e, string'in sayıya ya da herhangi bir değerin boolean'a dönmesi gibi. +, == veya if gibi operatörler beklemedikleri bir tiple karşılaştığında implicit (örtük) olarak, siz Number(x), String(x) ya da Boolean(x) çağırdığınızda ise explicit (açık) olarak gerçekleşir.

Implicit ve explicit coercion arasındaki fark nedir?

Explicit coercion, dönüşümü bilerek yaptığınız durumdur: Number("42"), String(99), Boolean(value). Implicit coercion ise operatörün arka planda sessizce dönüşümü tetiklemesidir: "5" - 2 sonucu 3 verir ama "5" + 2 size "52" döner. Explicit olanı okuması kolay ve tahmin edilebilirdir; implicit olanı ise "bu neden NaN döndü ya" dediğiniz hataların ana kaynağıdır.

JavaScript'te string'i sayıya nasıl çeviririm?

Sıkı bir dönüşüm için Number("42") kullanın (geçerli bir sayı değilse NaN döner). Daha dağınık bir string'in başındaki sayıyı okumak istiyorsanız parseInt("42px", 10) veya parseFloat("3.14em") iş görür. Tekli + operatörü (+"42") de Number() ile aynı işi yapar ama koda hızlı göz gezdirirken gözden kaçması çok kolaydır.

[] + [] neden boş string döndürüyor?

İki dizi için + operatörünün anlamlı bir sayısal işlemi yok, bu yüzden JavaScript ikisini de string'e çeviriyor. Diziler stringe dönerken elemanlarını virgülle birleştiriyor; boş dizi de "" oluyor. Yani [] + [] aslında "" + "" haline geliyor ve sonuç "" oluyor. Hoş bir parti numarası ama aynı zamanda + operatörünü primitive olmayan değerlerle kullanmamak için iyi bir sebep.

Coddy ile kodlamayı öğren

BAŞLA