Menu
Playground'da Dene

JavaScript Eşitlik Operatörleri: == vs === ve Object.is

JavaScript'te eşitlik gerçekte nasıl çalışır? == ile ==='ün farkı, NaN'ın tuhaflıkları, nesne karşılaştırması ve Object.is'i ne zaman kullanmalısın — hepsi örneklerle.

"Bunlar eşit mi?" Sorusunu Sormanın İki Yolu

JavaScript'te iki farklı eşitlik operatörü var: === (katı eşitlik) ve == (gevşek eşitlik). Görünüşte neredeyse aynılar ama davranışları bambaşka.

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

=== hem iki operandın aynı tipte olup olmadığını hem de aynı değere sahip olup olmadığını kontrol eder. == ise önce operandları ortak bir tipe çevirir, sonra karşılaştırır. İşte JavaScript'in eşitlik konusundaki kötü şöhretinin büyük bölümü bu dönüşümden — yani tip dönüşümünden — kaynaklanır.

Kısacası: varsayılan olarak === kullanın. Uzun hikâyeyi de bir kere okumaya değer; böylece neyden vazgeçtiğinizi bilirsiniz.

Katı eşitlik: muhtemelen istediğiniz şey bu

=== yalnızca iki taraf hem tip hem de değer olarak eşleştiğinde true döner. Ne tip dönüşümü vardır, ne de sürprizler:

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

Tipler uyuşmuyorsa cevap anında false olur. Uyuşuyorsa JavaScript değerleri karşılaştırır. İlkel tiplerde (primitive) bu bir değer karşılaştırmasıdır; nesnelerde ise referans karşılaştırmasıdır — buna birazdan daha detaylı değineceğiz.

!== ise katı eşitsizlik operatörüdür ve aynı kuralları tersten uygular.

Gevşek eşitlik: perde arkasındaki tip dönüşümü

== operatörü, iki tarafın farklı tiplerde olmasına izin verir. Karşılaştırmadan önce tarafları aynı tipe getirmek için bir dizi tip dönüşümü (coercion) devreye sokar:

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

Kesin kurallar spec'te yazılı ve aslında o kadar da kötü değiller; ama hata ayıklarken onları tek tek hatırlamak bambaşka bir mesele. "0" == false ifadesinin true dönmesi deneyimli geliştiricileri bile tuzağa düşürür. [] == false de öyle (bu da true, çünkü dizi önce ""'ye, o da 0'a dönüşüyor).

İşte tam da bu yüzden çoğu stil rehberi — ve ESLint'in eqeqeq kuralı — varsayılan olarak === kullanmanı söyler. Tek bir karakter fazladan yazarsın, karşılığında aklında tutabileceğin kurallarla çalışırsın.

İşine Yarayacak Tek == Kalıbı

Bilmeye değer tek bir gevşek eşitlik kalıbı var: x == null, x değeri null ya da undefined olduğunda true, diğer her durumda false döner.

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

Tam karşılığı x === null || x === undefined ifadesidir; çalışır ama göze biraz daha kalabalık gelir. Bu yüzden pek çok kod tabanı == null kullanımını tek istisna olarak kabul eder. Hangi yolu seçerseniz seçin, tutarlı olun.

JavaScript'te nesneler referansa göre karşılaştırılır

Nesneler, diziler ve fonksiyonlar söz konusu olduğunda hem === hem de == aynı soruyu sorar: "İki taraf da bellekte aynı nesneye mi işaret ediyor?" Yani "içerikleri aynı mı?" diye sormaz.

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

İçerikleri birebir aynı olan iki nesne literali yine de iki ayrı nesnedir. Bu konu herkesi en az bir kez tökezletir.

Değer bazlı karşılaştırma için ya kendi yardımcı fonksiyonunu yazarsın, bir kütüphane kullanırsın (lodash.isequal) ya da basit düz nesneler için JSON.stringify ile serileştirirsin:

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

JSON.stringify sadece basit verilerde işe yarar — fonksiyonları, undefined değerini ve sembolleri yok sayar; ayrıca farklı motorlarda her nesne için anahtar sırasının aynı olacağı garanti edilmez. Yani pratik bir hızlı kontrol, genel geçer bir çözüm değil.

NaN hiçbir şeye eşit değildir

NaN ("not a number"), JavaScript'in anlamlı bir sonuç üretemediği sayısal işlemlerde döndürdüğü değerdir — 0/0, Number("abc"), Math.sqrt(-1) gibi. Taraflardan biri NaN olduğunda her iki eşitlik operatörü de false döner; hatta iki taraf da NaN olsa bile sonuç değişmez:

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

NaN kontrolü için Number.isNaN(value) kullanın. Eski global isNaN fonksiyonundan uzak durun; çünkü argümanını önce tip dönüşümüne tabi tutuyor. Yani isNaN("hello") size true döndürür — ki bu neredeyse hiçbir zaman istediğiniz şey değildir.

Object.is: İki Küçük Farkla === Gibi

Object.is(a, b), iki uç durum dışında tıpkı === gibi davranır:

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

Çoğu zaman ihtiyacın olan şey === operatörüdür. Object.is'e yalnızca NaN'ı kendisine eşit saymak ya da +0 ile -0'ı birbirinden ayırmak gerektiğinde başvur — ikisi de nadir durumlar ama sayısal kodda veya framework içlerinde zaman zaman kritik olabiliyor (React, state karşılaştırmaları için Object.is kullanıyor).

Eşitsizlik Operatörleri de Aynı Mantığı İzler

!== katı, != gevşektir; aynı öneri burada da geçerli:

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

Varsayılan olarak !== kullanın. Eğer == null kullanımına zaten izin verdiyseniz, "ne null ne undefined" kontrolü için karşılığı olan != null'a da izin verebilirsiniz.

Değerleri Karşılaştırma İçin Kontrol Listesi

İki değeri karşılaştırmanız gerektiğinde şu adımları aklınızda tutun:

  • İlkel tipler ve tipler aynı mı? === kullanın.
  • null veya undefined kontrolü mü yapıyorsunuz? Stil rehberiniz izin veriyorsa x == null gayet yeterli; değilse x === null || x === undefined yazın.
  • NaN kontrolü mü lazım? Number.isNaN(x) ile yapın.
  • Nesneleri kimliklerine göre mi karşılaştırıyorsunuz? === tam olarak bunu yapar.
  • Nesneleri içeriklerine göre mi karşılaştırıyorsunuz? Kendi yardımcı fonksiyonunuzu yazın, bir kütüphane kullanın ya da JSON'a çevirip karşılaştırın. Yerleşik operatörler burada işinizi görmez.

==='i varsayılan seçeneğiniz yapın, =='yi yalnızca == null durumu için özel bir araç olarak görün; böylece JavaScript'in SSS listelerini dolduran eşitlik tuhaflıklarından uzak durursunuz.

Sırada: Operatörler

Eşitlik, JavaScript'teki operatör ailesinin yalnızca bir parçası. Bir sonraki yazıda geri kalanları — aritmetik, mantıksal, atama ve günlük kodda sıkça başvuracağınız kısa-form operatörleri — tek tek ele alacağız.

Sıkça Sorulan Sorular

JavaScript'te == ile === arasındaki fark nedir?

=== katı eşitliktir: sadece iki operand aynı tipteyse ve aynı değere sahipse true döner. == ise gevşek eşitlik — karşılaştırmadan önce operandları aynı tipe dönüştürür. Yani 1 === '1' sonucu false iken, 1 == '1' sonucu true olur çünkü == önce string'i sayıya çevirir.

Her zaman === kullanmalı mıyım?

Genel kural olarak evet. === öngörülebilir ve kuralları akılda tutması kolay. Tek yaygın istisna x == null kalıbı: bu hem null hem de undefined değerini tek seferde yakaladığı için pratiktir. ESLint'in eqeqeq kuralı gibi linter'lar zaten === kullanımını zorunlu kılar ve bu kalıba özel izin verir.

NaN === NaN neden false döner?

IEEE 754 standardına göre NaN hiçbir şeye, hatta kendisine bile eşit değildir. Bu yüzden NaN söz konusu olduğunda tüm eşitlik operatörleri false döner. Bir değerin NaN olup olmadığını kontrol etmek için Number.isNaN(x) kullan; ya da Object.is(NaN, NaN) — bu true döner.

JavaScript'te iki nesneyi eşitlik açısından nasıl karşılaştırırım?

Hem == hem de === nesneleri içeriklerine göre değil, referanslarına göre karşılaştırır. Örneğin {a: 1} === {a: 1} sonucu false'tur çünkü bunlar bellekte iki farklı nesnedir. Değere göre karşılaştırmak istiyorsan ya kendi kontrolünü yazmalısın, ya Lodash'ın isEqual gibi bir yardımcısını kullanmalısın ya da basit düz nesnelerde JSON.stringify ile serileştirip karşılaştırabilirsin.

Coddy ile kodlamayı öğren

BAŞLA