JSLint '===' bekleniyordu ve bunun yerine '==' gördü


90

Geçenlerde bu hatayla karşılaştığımda kodumun bir kısmını JSLint üzerinden çalıştırıyordum. Yine de bu hatayla ilgili komik olduğunu düşündüğüm şey, otomatik olarak all == 'un === olması gerektiğini varsaymasıdır.

Bu gerçekten mantıklı mı? Türleri karşılaştırmak istemeyeceğiniz birçok örnek görebiliyordum ve bunun aslında sorunlara neden olabileceğinden endişeleniyorum.

"Beklenen" kelimesi bunun HER ZAMAN yapılması gerektiğini ima eder ..... Bana mantıklı gelmeyen budur.


7
JSLint ile buna ben de rastladım. == ile === arasında bir güncelleme yaptım ve aslında daha önce çalışan kodu bozdu.
kemiller2002

5
Kodunuz 100'den fazla satır içeriyorsa jslint'i geçmez, gerçekten imkansızdır.

3
"Kırmak" çok güçlü bir kelimedir. Kodunuzun anlamını değiştirdi. Bir myVar == nullkontrol yapıyorsanız , evet, büyük değişiklikler. ; ^) Crockford'un argümanı, kodun anlamını daha kesin hale getirdiği ve bunu tartışması zor.
13:52

Yanıtlar:


127

Tür dönüşümünün nasıl ===çalıştığını anlamaya çalışmadan körü körüne kullanan IMO, pek bir anlam ifade etmiyor.

Eşittir işleci ile ilgili temel korku== , karşılaştırılan türlere bağlı olan karşılaştırma kurallarının işleci geçişsiz hale getirebilmesidir, örneğin:

A == B AND
B == C

Bunu gerçekten garanti etmiyor:

A == C

Örneğin:

'0' == 0;   // true
 0  == '';  // true
'0' == '';  // false

===Aynı türdeki değerleri karşılaştırdığınızda Katı Eşittir operatörü gerçekten gerekli değildir, en yaygın örnek:

if (typeof foo == "function") {
  //..
}

Her zaman bir dizetypeof olan işlecin sonucunu bir dize değişmezi ile karşılaştırıyoruz ...

Eğer tip zorlama kuralları bildiğinizde şeydir Veya, örneğin, çek nullveya undefinedşey:

if (foo == null) {
  // foo is null or undefined
}

// Vs. the following non-sense version:

if (foo === null || typeof foo === "undefined") {
  // foo is null or undefined
}

1
JSLint'in bu kuralından nefret ediyorum. Bence asıl sorun, insanların operatörleri anlamadıkları şekillerde kullanmamaları gerektiğidir (ironik bir şekilde bunlar genellikle '===' yerine '==' körü körüne değiştiren aynı tür insanlardır). Elbette, 0 sayısını çeşitli dizelerle karşılaştırırken ortaya çıkan birkaç olağan durum vardır, ancak 0 == 'bu bir dizedir' gibi ilgisiz verileri karşılaştırıyorsanız - Kodunuzun muhtemelen çift eşitten daha büyük sorunları vardır! Hangi türlerle uğraştığınızdan eminseniz ve == ile nasıl etkileşime girdiklerini tam olarak biliyorsanız, o zaman onu kullanmanız gerektiğini düşünüyorum.
Jon

3
@Jon ===Operatörün amacı kod netliğidir . Hiçbir ==zaman kimlik operatörü kadar açık ve anlaşılır olmayacağı için kullanılması makul bir durum yoktur . Operatörleri anlayıp anlamadığınızla ilgili değil, kodunuzu neredeyse hiçbir masraf olmadan daha kolay okunabilir kılanı kullanmakla ilgili. Kimlik operatörüne karşı çıkan tek geliştiriciler, solo geliştiriciler ve takım halinde çalışmayan kişilerdir. Tanım gereği, kodu yeterince göz önünde bulundurmayan insanlar.
Alternatif

2
== null karşılaştırmasının neredeyse gerekli olduğunu düşünüyorum. Kodunuz iyi test edilirse sorun daha da önemsiz hale gelir.
Jon

1
Aslında, gerekli testi gerçekleştirmek için == kullanmanın gerekli olduğu zamanlar vardır. foo.toString () öngörülebilir bir şekilde çalışacaksa ve düz bir dizenin bu çıktıya karşı test edilmesi gerekiyorsa, foo == stringToTest yazmak foo.toString () === stringToTest'ten çok daha temizdir.
Crispen Smith

2
@Alternatex Eğer konu açıklık olsaydı, bunu TRIPLE eşittir yapmamalıydılar! Yeni başlayanlar bunu anlamıyor. En az çift eşittir diğer dillerden bilinmektedir. Ayrıca, there is no reasonable situationbüyük bir yanlışlıktır. (Yerel) Javascript türleri Numberve String. Varlıkları, Javascript yazarlarının akıllarında belirli kullanım durumları olduğunu kanıtlıyor ==. Gerçekten new String('hi') === 'hi'değerlendirmenin falseçok net olduğunu düşünüyor musunuz ? Lütfen fonksiyon argümanınızı 'hi'hem String hem de string kabul etmeye karşı test eden bir kod parçası yazın ve bana bunun net olduğunu söyleyin.
Stijn de Witt

25

JSLint doğası gereği Javascript sözdiziminin izin verdiğinden daha savunmacıdır.

JSLint belgelerinden:

==Ve !=operatörler karşılaştırarak önce tip zorlama yok. Bu kötü çünkü doğru olmasına neden oluyor ' \t\r\n' == 0. Bu, tür hatalarını maskeleyebilir.

Aşağıdaki değerlerden herhangi biriyle karşılaştırırken, ===veya !==işleçlerini kullanın (bunlar tür zorlaması yapmazlar):0 '' undefined null false true

Bir değerin yalnızca doğru veya yanlış olmasını önemsiyorsanız , kısa biçimi kullanın. Onun yerine

(foo != 0)

sadece söyle

(foo)

ve yerine

(foo == 0)

söyle

(!foo)

===Ve !==operatörler tercih edilir.


8
JSLint'teki insanların asla çıkamadıkları çok yüksek fildişi kulelerde çalıştıkları sonucuna varmalıyım. Javascript, operatörle kullanılmak üzere tasarlanmıştır== . ===JSLint o kullanarak gibi göstermeye çalışır ... özel bir durumdur ==Ancak bu deneyin ... nasılsa yanlış olur: var x = 4, y = new Number(4); if (x == y) {alert('Javascript depends on == just embrace it!');}. İlkel türler, bunların yerine geçen karşılık gelen sınıflara sahiptir ( Number, String) ve Javascript, ==bunları doğal olarak karşılaştırmak için operatöre bağlıdır .
Stijn de Witt

17

JSLint'in, iyi bir JavaScript'in ne olması gerektiği konusunda bir kişinin fikrini güçlendirdiğini unutmayın. Önerdiği değişiklikleri uygularken yine de sağduyu kullanmanız gerekir.

Genel olarak, türü ve değeri karşılaştırmak kodunuzu daha güvenli hale getirir (tür dönüştürme düşündüğünüz şeyi yapmadığında beklenmedik davranışlarla karşılaşmazsınız).


4
Ayrıca bir programcı kadar bağlam açısından akıllı olamaz. Sadece çoğu kullanıcının sistemde bulunan otomatik tür dönüştürme ile tetiklenmesi temelinde çalışıyor (şiddet gibi - "bastırılmam için yardım edin!")
Rudu

14

Üçlü eşit, çift eşitten farklıdır çünkü iki tarafın aynı değer olup olmadığını kontrol etmenin yanı sıra, üçlü eşit aynı veri türünde olup olmadıklarını da kontrol eder.

Yani ("4" == 4), oysa doğrudur ("4" === 4)yanlıştır.

Üçlü eşitlik ayrıca biraz daha hızlı çalışır, çünkü JavaScript'in size cevap vermeden önce herhangi bir tür dönüşümü yapmakla zaman kaybetmesi gerekmez.

JSLint, belirsiz hataları azaltmak amacıyla kasıtlı olarak JavaScript kodunuzu olabildiğince sıkı hale getirmeyi amaçlamaktadır. Sizi veri türlerine saygı duymaya zorlayacak şekilde kodlamaya yönlendirmek için bu tür şeyleri vurgular.

Ancak JSLint ile ilgili iyi olan şey, sadece bir rehber olmasıdır. Sitede dedikleri gibi, çok iyi bir JavaScript programcısı olsanız bile, duygularınızı incitecektir. Ancak tavsiyesine uymak zorunda hissetmemelisiniz. Söylemesi gereken şeyi okuduysanız ve anladıysanız, ancak kodunuzun bozulmayacağından eminseniz, o zaman hiçbir şeyi değiştirme zorunluluğunuz yoktur.

Hatta JSLint'e, hakkında hiçbir şey yapmayacağınıza dair uyarılarla bombardımana tutulmak istemiyorsanız, kontrol kategorilerini görmezden gelmesini söyleyebilirsiniz.


3
"=== nedir" diye sormadım, bu yüzden neden cevapladığınızdan emin değilim.
Metropolis

8
@Metropolis: Başka bir sebep yoksa, cevabı başka birinin bilmediği bir şekilde okuması durumunda arka plan olarak. Yine de sorunuzu bundan sonraki paragraflarda cevaplamaya çalıştım.
Spudley

Ek ve faydalı bilgiler için @Spudley + 1
Ben Junior

1
evet, 10-100 kat daha hızlı: jsperf hız testi
vladkras

8

Http://javascript.crockford.com/code.html'den bir alıntı :

=== ve! == Operatörler.

=== ve! == operatörlerini kullanmak neredeyse her zaman daha iyidir. == ve! = Operatörleri tür zorlaması yapar. Özellikle, yanlış değerlerle karşılaştırmak için == kullanmayın.

JSLint çok katıdır, 'webjslint.js' kendi doğrulamasını bile geçmez.


Güzel açıklama. webjslint.jsDoğrulamamakla ilgili bu doğru - şu anda gördüğüm hataların çoğu aralıklarla ilgili olsa da. Açıkçası, JSLint kullanarak JavaScript'i incelerken sağduyu ve makul muhakeme kullanmak gerekir.
hotshot309

Sözcüğün kullanılması, alwaysbu alıntıyı bilgelik olarak otomatik olarak diskalifiye eder. Akıllı programcılar dogmatik değildir. Verilen durumda en iyi olanı kullanırlar. Ve sadece a ile reddetmekle kalmayıp, dilin özüne yerleştirilmiş herhangi bir aracı kabul ediyor ve benimsiyorlar just never touch it. Alt satır: Kodum daha kısa (ve sadece bir =karakter kaydetmekten değil ), bu nedenle sitem daha hızlı yükleniyor, daha az bant genişliği maliyetiyle, böylece kullanıcım daha iyi hizmet veriyor.
Stijn de Witt

4

Yanlışlık için test etmek istiyorsanız. JSLint izin vermiyor

if (foo == null)

ama izin veriyor

if (!foo)

===JSLint'in önerdiği kullanın .
tıklama tuzağı

1
@NarawaGames Bu çözüm tamamen kabul edilebilir.

Bu cevap iyi değil. Mesele şu ki, her ikisi de başka bir şey ifade ediyor. foo == nullnull veya undefined olup olmadığını denetler. !foonull, undefined, 0 ve boş dizeyi denetler.
Markos

@Markos Bu yanıt, JSLint'i mutlu etmek ve kod mantığınızı sağlam tutmak için yararlı bir alternatiftir, tam olarak eşdeğer değildir. Bu yüzden cevabın önüne "Yanlış uyumu kontrol ediyorsanız"
ekledim

3

Bu soruyu açıklamaya yardımcı olmak ve ayrıca NetBeans (nereden) 7.3'ün neden bu uyarıyı göstermeye başladığını açıklamak için bu, birisi bunu bir hata olarak bildirdiğinde NetBeans hata izleyicisindeki yanıtın bir özetidir:

JavaScript'te == yerine === kullanmak iyi bir uygulamadır.

== ve! = Operatörleri, karşılaştırmadan önce tür zorlaması yapar. Bu kötü çünkü '\ t \ r \ n' == 0'ın doğru olmasına neden oluyor. Bu, tür hatalarını maskeleyebilir. JSLint, =='un doğru kullanılıp kullanılmadığını güvenilir bir şekilde belirleyemez, bu nedenle en iyisi == ve! = Kullanmamak ve bunun yerine her zaman daha güvenilir === ve! == operatörlerini kullanmaktır.

Referans


1
Bu hatayı şimdi Netbeans kullanarak da buldum. Sağladıkları tuhaf örnek vaka nedeniyle bunu uyarı ciddiyetiyle ele almaları garip.
omikes

1
Demek istediğim, bu doğru, ancak kişinin karşılaştırılan iki şeyin aynı türden olacağını bildiği birçok kullanım durumu var, bu nedenle bir satırbaşı ile sayı ile karşılaştırılabilecek bu garip durum nedeniyle garip görünüyor sıfır, tüm == kullanımlarının yanlış kabul edilmesinin sebebidir. Tür dönüşümü yapılmadığından === daha hızlı olsa da öğreniyorum. Bunu net fasulyelerden önce bulmadığıma şaşırdım.
omikes

@oMiKeY Evet Ne demek istediğini anlıyorum, daha gerçekçi örnekler verebilirlerdi!
EM-Creations

2

Aslında sorunlara neden olamaz, sadece size tavsiyelerde bulunur. Al ya da git. Bununla birlikte, ne kadar zeki olduğundan emin değilim. Bunu bir sorun olarak sunmadığı bağlamlar olabilir.


1
ama "Beklenen" kelimesi neden kullanılıyor? Bu, her zaman bunu yapman gerektiğini düşündürüyor.
Metropolis

4
Değerlendirici, doğrulamaya çalıştığı için geçerli bir yanıt arıyor. Geçerli bir yanıt alamazsa, beklediği gibi değildir. Doğrulayıcı, her şeyin yolunda olduğu varsayımıyla başlar ve ardından kodu geçerken hataları işaret eder. Geçersiz bir cevabın ne olduğunu mutlaka anlamaz, sadece geçersiz bir cevabı gördüğünde bilir. Kötü olanın kurallarına göre kasıtlı olarak kötü kod arayarak ters yönde de çalışabilir. Beyaz listeye ve kara listeye alma.
Rushyo

Soru "Bu gerçekten mantıklı mı?" İdi. Bu soru göz önüne alındığında, evet, öyle. Ayrıca beş yıl önceydi . İsa.
Rushyo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.