Profesyonel bir matematikçi olarak Javscript'in aynılık operatöründe ==
(ayrıca "soyut karşılaştırma", "gevşek eşitlik" olarak da adlandırılır ) , varlıklar arasında dönüşlü , simetrik ve geçişli olmak üzere bir denklik ilişkisi kurma girişimi görüyorum . Ne yazık ki, bu üç temel özellikten ikisi başarısız:
A == A
yanlış olabilir, örneğin
NaN == NaN // false
A == B
ve B == C
birlikte ima etme A == C
, örn.
'1' == 1 // true
1 == '01' // true
'1' == '01' // false
Sadece simetrik özellik hayatta kalır:
A == B
B == A
hangi ihlalin her durumda muhtemelen düşünülemez olduğunu ve ciddi isyanlara yol açacağını ima eder ;)
Eşdeğerlik ilişkileri neden önemlidir?
Çünkü bu, çok sayıda örnek ve uygulama tarafından desteklenen en önemli ve en yaygın ilişki türüdür. En önemli uygulama, varlıkların , ilişkilerin anlaşılmasının çok uygun ve sezgisel bir yolu olan denklik sınıflarına ayrıştırılmasıdır . Eşitlik olmamak ve eşdeğerlik sınıflarının olmamasına yol açar, bu da sezgisel olma ve iyi bilinen gereksiz karmaşıklıklara yol açar.
==
Eşit olmayan bir ilişki için yazmak neden bu kadar korkunç bir fikir ?
Çünkü, benzerliği, eşitliği, uyumu, izomorfizmi, kimliği vb. İlginç bir ilişki olduğu için tanıdıklığımızı ve sezgimizi kırıyor.
Tür dönüşümü
Sezgisel bir denkliğe güvenmek yerine, JavaScript tür dönüştürmeyi sağlar:
Eşitlik operatörü, eğer aynı tipte değilse, operandları dönüştürür, sonra sıkı bir karşılaştırma yapar.
Ancak tür dönüşümü nasıl tanımlanır? Çok sayıda istisna dışında bir dizi karmaşık kural aracılığıyla mı?
Eşitlik ilişkisi kurmaya çalışıldı
Boolean. Açıkça true
ve false
aynı değildir ve farklı sınıfta olmalıdır.
Sayılar. Neyse ki, sayıların eşitliği zaten iki farklı sayının asla aynı denklik sınıfında olmadığı iyi tanımlanmıştır. Matematikte budur. JavaScript içinde sayısının kavramıdır biraz deforme daha egzotik varlığı ile de -0
, Infinity
ve -Infinity
. Matematiksel sezgilerimiz , aynı sınıfta olmaları 0
ve -0
olması gerektiğini (gerçekte -0 === 0
olduğu gibi true
) belirtir, oysa ki sonsuzlukların her biri ayrı bir sınıftır.
Sayılar ve Booleanlar. Sayı sınıfları göz önüne alındığında, booleanları nereye koyacağız? false
benzer olur 0
ise, true
benzer olur 1
, ancak başka bir numara:
true == 1 // true
true == 2 // false
Buraya true
birlikte koymak için herhangi bir mantık var 1
mı? Kuşkusuz 1
ayırt edilir, ama öyle -1
. Şahsen dönüştürmek true
için bir neden görmüyorum 1
.
Ve daha da kötüleşiyor:
true + 2 // 3
true - 1 // 0
Yani true
gerçekten 1
tüm sayılar arasında dönüştürülür ! Mantıklı mı? Sezgisel mi? Cevap egzersiz olarak bırakılmıştır;)
Peki ya bu:
1 && true // true
2 && true // true
Sadece boolean x
ile x && true
varlık true
olduğunu x = true
. Bu da hem 1
ve 2
(ve diğer herhangi bir sayının 0
) dönüştürdüğünü kanıtlar true
! Varlık - Gösterdiği dönüşüm diğer önemli özelliği başarısız olmasıdır bijection . Yani iki farklı varlık aynı birine dönüştürebilir. Bu, başlı başına büyük bir sorun olmak zorunda değildir. Bu problemi, ne demek istiyorsak onu "aynılık" veya "gevşek eşitlik" ilişkisini tanımlamak için kullandığımız zaman büyük problem ortaya çıkar. Ancak bir şey açıktır - bir denklik ilişkisi olmayacak ve denklik sınıfları aracılığıyla sezgisel bir şekilde tanımlanmayacaktır.
Ama daha iyisini yapabilir miyiz?
En azından matematiksel olarak - kesinlikle evet! Boole'ler ve sayılar arasında basit bir denklik ilişkisi sadece false
ve 0
aynı sınıfta olmakla kurulabilir . Yani false == 0
önemsiz olmayan tek eşitlik olacaktır.
Peki ya teller?
Sayılara dönüştürmek için başlangıçtaki ve sondaki boşluklardan dizeleri kırpabiliriz, ayrıca öndeki sıfırları da görmezden gelebiliriz:
' 000 ' == 0 // true
' 0010 ' == 10 // true
Böylece bir string için basit bir kural elde ediyoruz - boşlukları ve öndeki sıfırları kırpın. Bir sayı veya boş bir dize alırız, bu durumda bu sayıya veya sıfıra dönüştürürüz. Ya da bir sayı alamıyoruz, bu durumda dönüştürmüyoruz ve yeni bir ilişki kurmuyoruz.
Bu şekilde, toplam boole, sayı ve karakter dizisi üzerinde mükemmel bir denklik ilişkisi elde edebiliriz! Bunun dışında ... JavaScript tasarımcılarının açıkça başka bir fikri var:
' ' == '' // false
Böylece, her ikisine de dönüşen iki tel 0
aniden birbirine benzemez! Neden ya da neden? Kurala göre, tamamen eşit olduklarında dizgiler kesin olarak eşit olur! Yalnızca bu kural gördüğümüz gibi geçişliliği bozmaz, aynı zamanda gereksizdir! ==
Onu diğeriyle tamamen aynı yapmak için başka bir operatör yaratmanın amacı nedir ===
?
Sonuç
Gevşek eşitlik operatörü ==
, bazı temel matematik yasalarına uyması halinde çok faydalı olabilirdi. Ancak ne yazık ki olmadığı gibi, faydası da zarar görüyor.