JSLint erwartete '===' und sah stattdessen '=='

89

Kürzlich habe ich einen Teil meines Codes über JSLint ausgeführt, als ich auf diesen Fehler stieß. Das, was ich an diesem Fehler lustig finde, ist, dass automatisch davon ausgegangen wird, dass alle == === sein sollten.

Macht das wirklich Sinn? Ich konnte viele Fälle sehen, in denen Sie den Typ nicht vergleichen möchten, und ich mache mir Sorgen, dass dies tatsächlich Probleme verursachen könnte.

Das Wort "Erwartet" würde bedeuten, dass dies JEDES Mal getan werden sollte ..... Das macht für mich keinen Sinn.

Metropole
quelle
7
Ich bin auch mit JSLint darauf gestoßen. Ich habe ein Update von == auf === gemacht und es hat tatsächlich den zuvor funktionierenden Code gebrochen.
kemiller2002
4
Wenn Ihr Code mehr als 100 Zeilen enthält, wird er jslint nicht passieren. Es ist wirklich unmöglich.
3
"Brach" ist ein zu starkes Wort. Es hat die Bedeutung Ihres Codes geändert. Wenn Sie eine myVar == nullÜberprüfung durchgeführt haben, ja, große Änderungen. ; ^) Crockfords Argument ist, dass es die Bedeutung des Codes präzisiert hat, und das ist schwer zu argumentieren.
Ruffin

Antworten:

126

IMO, blind zu verwenden ===, ohne zu verstehen, wie die Typkonvertierung funktioniert, macht wenig Sinn.

Die Hauptangst gegenüber dem Operator "Gleich" ==besteht darin, dass die Vergleichsregeln in Abhängigkeit von den verglichenen Typen den Operator nicht transitiv machen können, beispielsweise wenn:

A == B AND
B == C

Garantiert das nicht wirklich:

A == C

Beispielsweise:

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

Der Operator Strict Equals ===ist nicht unbedingt erforderlich, wenn Sie Werte desselben Typs vergleichen. Dies ist das häufigste Beispiel:

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

Wir vergleichen das Ergebnis des typeofOperators, der immer eine Zeichenfolge ist , mit einem Zeichenfolgenliteral ...

Oder wenn Sie beispielsweise die Regeln für Typzwang kennen, überprüfen Sie, ob etwas vorhanden ist nulloder nicht undefined:

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
}
Christian C. Salvadó
quelle
1
Ich hasse diese Regel von JSLint. Ich denke, das eigentliche Problem ist, dass die Leute Operatoren nicht auf eine Weise verwenden sollten, die sie nicht verstehen (ironischerweise sind dies oft die gleichen Leute, die blind '===' durch '==' ersetzen würden). Sicher, es gibt einige übliche Fälle, die beim Vergleichen der Zahl 0 mit verschiedenen Zeichenfolgen auftreten, aber wenn Sie nicht verwandte Daten wie 0 == 'Dies ist eine Zeichenfolge' vergleichen - Ihr Code hat wahrscheinlich größere Probleme als doppelt gleich! Wenn Sie sicher wissen, mit welchen Typen Sie es zu tun haben und wie genau sie mit == interagieren, sollten Sie es verwenden.
Jon
3
@ Jon Der Punkt des ===Operators ist die Klarheit des Codes. Es gibt keine vernünftige Situation, ==da diese niemals so klar und verständlich sein wird wie der Identitätsoperator. Es geht nicht darum, ob Sie die Operatoren verstehen oder nicht, es geht darum, den zu verwenden, der Ihren Code fast ohne Kosten leichter lesbar macht. Die einzigen Entwickler, die gegen den Identitätsoperator argumentieren, sind Einzelentwickler und Leute, die nicht in Teams arbeiten. Per Definition werden Personen, deren Code nicht von genügend Augen überprüft wird.
Alternatex
2
Ich finde den == Null-Vergleich fast unabdingbar. Das Problem wird noch weniger wichtig, wenn Ihr Code gut getestet ist.
Jon
1
Es gibt tatsächlich Zeiten, in denen die Verwendung von == unerlässlich ist, um den erforderlichen Test durchzuführen. Wenn foo.toString () eine vorhersehbare Leistung erbringt und eine einfache Zeichenfolge gegen diese Ausgabe getestet werden muss, ist das Schreiben von foo == stringToTest viel sauberer als foo.toString () === stringToTest.
Crispen Smith
1
@Alternatex Wenn der Punkt Klarheit wäre, hätten sie es nicht TRIPLE gleich machen sollen! Kein Anfänger versteht es. Mindestens doppelt gleich ist aus anderen Sprachen bekannt. Auch there is no reasonable situationist eine grobe Falschangabe. Denken Sie an (native) Javascript-Typen Numberund String. Ihre Existenz beweist, dass die Javascript-Autoren bestimmte Anwendungsfälle im Auge hatten ==. Denken Sie wirklich, dass die new String('hi') === 'hi'Bewertung zu falsesehr klar ist? Bitte schreiben Sie ein Code-Snippet, das Ihr Funktionsargument gegen das 'hi'Akzeptieren von String und String testet, und sagen Sie mir, dass dies klar ist.
Stijn de Witt
25

JSLint ist von Natur aus defensiver als die Javascript-Syntax zulässt.

Aus der JSLint-Dokumentation:

Die Operatoren ==und !=geben vor dem Vergleich Zwang ein. Das ist schlecht, weil es ' \t\r\n' == 0wahr ist. Dies kann Typfehler maskieren.

Verwenden Sie beim Vergleich mit einem der folgenden Werte die Operatoren ===oder !==(die keinen Typ erzwingen):0 '' undefined null false true

Wenn Sie sich nur darum kümmern, dass ein Wert wahr oder falsch ist , verwenden Sie die Kurzform. Anstatt

(foo != 0)

Sag nur

(foo)

und statt

(foo == 0)

sagen

(!foo)

Die ===und !==Operatoren werden bevorzugt.

Daniel Vandersluis
quelle
8
Ich muss zu dem Schluss kommen, dass die Leute von JSLint in einem sehr hohen Elfenbeinturm arbeiten, aus dem sie nie herauskommen. Javascript wurde entworfen , mit dem zu verwendenden ==Operator. Das ===ist ein besonderer Fall ... versucht JSLint es scheint , wie mit ==irgendwie falsch wäre ... Aber versuchen Sie dies: var x = 4, y = new Number(4); if (x == y) {alert('Javascript depends on == just embrace it!');}. Primitive Typen haben entsprechende Klassen, die sie ersetzen ( Number, String), und Javascript hängt vom ==Operator ab, um diese natürlich zu vergleichen.
Stijn de Witt
17

Beachten Sie, dass JSLint die Vorstellung einer Person erzwingt, was gutes JavaScript sein sollte. Sie müssen immer noch den gesunden Menschenverstand verwenden, wenn Sie die vorgeschlagenen Änderungen implementieren.

Im Allgemeinen wird durch das Vergleichen von Typ und Wert Ihr Code sicherer (Sie werden nicht auf unerwartetes Verhalten stoßen, wenn die Typkonvertierung nicht das tut, was Sie denken).

Justin Niessner
quelle
4
Außerdem kann es nicht so kontextbezogen sein wie ein Programmierer. Es funktioniert nur auf der Grundlage, dass die meisten Benutzer durch die dem System innewohnende automatische Typkonvertierung (wie Gewalt - "Hilfe, ich werde unterdrückt!")
Rudu
14

Triple-Equal unterscheidet sich von Double-Equal, da Triple-Equal nicht nur überprüft, ob beide Seiten den gleichen Wert haben, sondern auch überprüft, ob sie denselben Datentyp haben.

So ("4" == 4)ist wahr, während ("4" === 4)falsch ist.

Triple-Equal läuft auch etwas schneller, da JavaScript keine Zeit mit Typkonvertierungen verschwenden muss, bevor Sie die Antwort erhalten.

JSLint zielt bewusst darauf ab, Ihren JavaScript-Code so streng wie möglich zu gestalten, um obskure Fehler zu reduzieren. Es wird diese Art von Dingen hervorgehoben, um zu versuchen, Sie dazu zu bringen, auf eine Weise zu codieren, die Sie dazu zwingt, Datentypen zu respektieren.

Das Gute an JSLint ist jedoch, dass es nur eine Anleitung ist. Wie sie auf der Website sagen, wird es Ihre Gefühle verletzen, selbst wenn Sie ein sehr guter JavaScript-Programmierer sind. Aber Sie sollten sich nicht verpflichtet fühlen, seinem Rat zu folgen. Wenn Sie gelesen haben, was es zu sagen hat, und Sie es verstehen, aber Sie sicher sind, dass Ihr Code nicht kaputt geht, müssen Sie nichts ändern.

Sie können JSLint sogar anweisen, Überprüfungskategorien zu ignorieren, wenn Sie nicht mit Warnungen bombardiert werden möchten, gegen die Sie nichts unternehmen werden.

Spudley
quelle
3
Ich habe nicht "Was ist ===" gefragt, daher bin ich mir nicht sicher, warum Sie darauf geantwortet haben.
Metropolis
7
@ Metropolis: Wenn aus keinem anderen Grund, dann als Hintergrund für den Fall, dass jemand anderes die Antwort liest, der es nicht wusste. Ich habe jedoch versucht, Ihre Frage in den Absätzen danach zu beantworten.
Spudley
@Spudley + 1 für die zusätzlichen und nützlichen Informationen
Ben Junior
1
Ja, es ist 10-100 mal schneller: jsperf Geschwindigkeitstest
vladkras
8

Ein Zitat von http://javascript.crockford.com/code.html :

=== und! == Operatoren.

Es ist fast immer besser, die Operatoren === und! == zu verwenden. Die Operatoren == und! = Geben Zwang ein. Verwenden Sie insbesondere nicht ==, um mit falschen Werten zu vergleichen.

JSLint ist sehr streng, ihre 'webjslint.js' besteht nicht einmal ihre eigene Validierung.

Lekensteyn
quelle
Schöne Klarstellung. Das stimmt, webjslint.jswenn man nicht validiert - obwohl die meisten Fehler, die ich derzeit sehe, mit dem Abstand zu tun haben. Natürlich muss man bei der Überprüfung von JavaScript mit JSLint gesunden Menschenverstand und vernünftiges Urteilsvermögen verwenden.
hotshot309
Die Verwendung des Wortes alwaysdisqualifiziert dieses Zitat automatisch als Weisheit. Intelligente Programmierer sind nicht dogmatisch. Sie verwenden das, was in der gegebenen Situation am besten ist. Und sie begrüßen und begrüßen jedes Werkzeug, das in den Kern der Sprache eingebaut ist, und entlassen es nicht einfach mit einem just never touch it. Fazit: Mein Code ist kürzer (und nicht nur durch das Speichern eines =Zeichens), daher wird meine Website schneller und zu geringeren Bandbreitenkosten geladen, sodass mein Benutzer besser bedient wird.
Stijn de Witt
4

Wenn Sie auf Falschheit testen möchten. JSLint erlaubt nicht

if (foo == null)

aber erlaubt

if (!foo)
nano2nd
quelle
Verwenden Sie ===, was JSLint empfiehlt.
Clickbait
1
@NarawaGames Diese Lösung ist vollkommen akzeptabel.
Diese Antwort ist nicht gut. Die Sache ist, dass beide etwas anderes bedeuten. foo == nullprüft auf null oder undefiniert. !fooprüft auf null, undefiniert, 0 und leere Zeichenfolge.
Markos
@Markos Diese Antwort soll eine hilfreiche Alternative sein, um JSLint glücklich zu machen und Ihre Codelogik intakt zu halten, und nicht um ein genaues Äquivalent zu sein. Aus diesem Grund habe ich der Antwort "Wenn auf Falschheit geprüft" vorangestellt
nano2nd
3

Um diese Frage zu erklären und um zu erklären, warum NetBeans (ab) 7.3 diese Warnung anzeigt, ist dies ein Auszug aus der Antwort auf den NetBeans-Bug-Tracker, als jemand dies als Fehler meldete:

Es wird empfohlen, in JavaScript === anstelle von == zu verwenden.

Die Operatoren == und! = Geben vor dem Vergleich Zwang ein. Dies ist schlecht, da dadurch '\ t \ r \ n' == 0 wahr wird. Dies kann Typfehler maskieren. JSLint kann nicht zuverlässig feststellen, ob == korrekt verwendet wird. Daher ist es am besten, == und! = Überhaupt nicht zu verwenden und stattdessen immer die zuverlässigeren Operatoren === und! == Zu verwenden.

Referenz

EM-Kreationen
quelle
1
Ich habe diesen Fehler gerade mit Netbeans gefunden. Es ist seltsam, dass sie dies aufgrund des bizarren Beispielfalls, den sie zur Verfügung gestellt haben, mit Warnschwere behandeln würden.
Omikes
1
Ich meine, es ist wahr, aber es gibt viele Anwendungsfälle, in denen die Person weiß, dass die beiden verglichenen Dinge vom gleichen Typ sind, so dass es seltsam erscheint, dass aufgrund dieses seltsamen Falls ein Wagenrücklauf mit der Anzahl verglichen werden könnte Null ist der Grund, warum alle Verwendungen von == als falsch angesehen werden. Ich finde jedoch heraus, dass === schneller ist, da keine Typkonvertierungen durchgeführt werden. Ich bin überrascht, dass ich das vor Netbeans nicht herausgefunden habe.
Omikes
@oMiKeY Ja, ich verstehe, was du meinst, sie hätten realistischere Beispiele geben können!
EM-Creations
2

Nun, es kann nicht wirklich Probleme verursachen, es gibt Ihnen nur Ratschläge. Nimm es oder lass es. Trotzdem bin ich mir nicht sicher, wie schlau es ist. Es kann durchaus Kontexte geben, in denen es nicht als Problem dargestellt wird.

Rushyo
quelle
aber warum wird das Wort "Erwartet" verwendet? Das klingt so, als ob Sie dies immer tun sollten.
Metropolis
4
Der Evaluator sucht nach einer gültigen Antwort, da er versucht, diese zu validieren. Wenn es keine gültige Antwort erhält, entspricht es nicht den Erwartungen. Der Validator geht von der Annahme aus, dass alles in Ordnung ist, und weist dann beim Durchlaufen des Codes auf Fehler hin. Es versteht nicht unbedingt, was eine ungültige Antwort ist, es weiß nur, wann es eine ungültige Antwort sieht. Es könnte auch umgekehrt funktionieren und absichtlich nach fehlerhaftem Code nach den Regeln des Schlechten suchen. Whitelisting vs Blacklisting.
Rushyo
Die Frage war "Macht das wirklich Sinn?". Angesichts dieser Frage ist dies der Fall. Es war auch vor fünf Jahren . Jesus.
Rushyo