Boolescher Wert in einer if-Anweisung

144

Heute habe ich eine Bemerkung über Code erhalten, wenn man bedenkt, wie ich überprüfe, ob eine Variable in einer Schulaufgabe wahr oder falsch ist.

Der Code, den ich geschrieben hatte, war ungefähr so:

var booleanValue = true;

function someFunction(){
    if(booleanValue === true){
        return "something";
    }
}

Sie sagten, es sei besser / ordentlicher, es so zu schreiben:

var booleanValue = true;

function someFunction(){
    if(booleanValue){
        return "something";
    }
}

Die Bemerkung, die ich über den Teil "=== true" erhalten habe, war, dass er nicht benötigt wurde und Verwirrung stiften könnte.

Meine Idee ist jedoch, dass es besser ist zu überprüfen, ob die Variable ein Boolescher Wert ist oder nicht, zumal Javascript eine lose typisierte Sprache ist.

Im zweiten Beispiel würde eine Zeichenfolge auch "etwas" zurückgeben;

Also meine Frage; Ist es ordentlicher, den Teil "=== true" in Zukunft zu verlieren, oder empfiehlt es sich, auch den Typ der Variablen zu überprüfen.

Bearbeiten: In meinem "echten" Code gibt der Boolesche Wert an, ob ein Bild gelöscht wurde oder nicht. Die einzigen Werte, die boolValue jemals haben sollte, sind wahr oder falsch.

0 und 1 sollten beispielsweise nicht in dieser Variablen enthalten sein.

DirkZz
quelle
4
Es ist lesbar und eine gute Praxis, ===
Piyas De
2
+1 für === true. Vermeidet Verwirrung !!
Gashu
1
@gashu Betrachten Sie die [0] === trueAuswertung als falsch.
RestingRobot
1
@Jlange sollte es nicht? Bitte erklären Sie
Gashu
Was ich damit gemeint habe, ist, dass, wenn Sie einfach nach einer "wahrheitsgemäßen" Existenz suchen wollten, diese Aussage fehlschlagen würde, obwohl sie als wahr ausgewertet werden sollte ([0] als wahr, aber nicht ohne Typkonvertierung). Es hängt wirklich davon ab, was Sie mit Ihrer Aussage erreichen wollen. Verwenden === trueSie diese Option, wenn Sie sicherstellen möchten, dass die Bedingung genau gleich ist true.
RestingRobot

Antworten:

222

Zunächst die Fakten:

if (booleanValue)

ifErfüllt die Aussage für jeden wahrheitsgemäßen Wert, booleanValueeinschließlich trueeiner Zahl ungleich Null, eines nicht leeren Zeichenfolgenwerts, einer Objekt- oder Arrayreferenz usw.

Andererseits:

if (booleanValue === true)

Dies erfüllt die ifBedingung nur, wenn sie booleanValuegenau gleich ist true. Kein anderer wahrer Wert wird es befriedigen.

Auf der anderen Seite, wenn Sie dies tun:

if (someVar == true)

Anschließend gibt Javascript den Befehl coerce ein true, um ihn an den Typ anzupassen , someVarund vergleicht dann die beiden Variablen. Es gibt viele Situationen, in denen dies wahrscheinlich nicht das ist, was man beabsichtigen würde. Aus diesem Grund möchten Sie in den meisten Fällen vermeiden, ==dass es ziemlich viele Regeln gibt, wie Javascript zwei Dinge zum gleichen Typ zwingt, und es sei denn, Sie verstehen alle diese Regeln und können alles vorhersehen, was der JS-Interpreter wann tun könnte Angesichts von zwei verschiedenen Typen (die die meisten JS-Entwickler nicht können) möchten Sie wahrscheinlich ==ganz vermeiden .

Als Beispiel dafür, wie verwirrend es sein kann:

var x;

x = 0;
console.log(x == true);   // false, as expected
console.log(x == false);  // true as expected

x = 1;
console.log(x == true);   // true, as expected
console.log(x == false);  // false as expected

x = 2;
console.log(x == true);   // false, ??
console.log(x == false);  // false 

Für den Wert 2würde man denken, dass dies 2ein wahrer Wert ist, also würde er sich positiv mit dem vergleichen true, aber so funktioniert der Typenzwang nicht. Es konvertiert den Wert für die rechte Hand so, dass er mit dem Typ des Werts für die linke Hand übereinstimmt, sodass er truein die Zahl konvertiert wird , 1damit verglichen wird, 2 == 1was sicherlich nicht das ist, was Sie wahrscheinlich beabsichtigt haben.

Also, Käufer aufgepasst. Es ist wahrscheinlich am besten, ==in fast allen Fällen zu vermeiden, es sei denn, Sie kennen explizit die Typen, die Sie vergleichen werden, und wissen, wie alle möglichen Typen von Zwangsalgorithmen funktionieren.


Es hängt also wirklich von den erwarteten Werten ab booleanValueund davon, wie der Code funktionieren soll. Wenn Sie im Voraus wissen, dass es immer nur einen trueoder falseWert haben wird, vergleichen Sie ihn explizit mit

if (booleanValue === true)

ist nur extra code und unnötig und

if (booleanValue)

ist kompakter und wohl sauberer / besser.

Wenn Sie andererseits nicht wissen, was sein booleanValuekönnte, und Sie testen möchten, ob es wirklich so eingestellt ist, dass truekeine anderen automatischen Typkonvertierungen zulässig sind, dann

if (booleanValue === true)

ist nicht nur eine gute Idee, sondern erforderlich.


Wenn Sie sich beispielsweise die Implementierung von .on()in jQuery ansehen , hat sie einen optionalen Rückgabewert. Wenn der Rückruf zurückkehrt false, stoppt jQuery automatisch die Weitergabe des Ereignisses. In diesem speziellen Fall falseüberprüfen sie , da jQuery die Weitergabe NUR stoppen möchte, wenn sie zurückgegeben wurde, die Rückgabe des Rückgabewerts, === falseweil sie nicht möchten undefinedoder 0oder ""oder irgendetwas anderes, das automatisch in false konvertiert, um auch den Vergleich zu erfüllen.

Hier ist beispielsweise der Rückrufcode für das jQuery-Ereignis:

ret = ( specialHandle || handleObj.handler ).apply( matched.elem, args );

if ( ret !== undefined ) {
     event.result = ret;
     if ( ret === false ) {
         event.preventDefault();
         event.stopPropagation();
     }
 }

Sie können sehen, dass jQuery explizit sucht ret === false.

Es gibt aber auch viele andere Stellen im jQuery-Code, an denen eine einfachere Überprüfung angebracht ist, wenn der Code dies wünscht. Beispielsweise:

// The DOM ready check for Internet Explorer
function doScrollCheck() {
    if ( jQuery.isReady ) {
        return;
    }
    ...
jfriend00
quelle
Ich habe eine Weile über diese Frage nachgedacht, aber keine Gelegenheit gehabt, jemanden zu finden, den ich fragen kann. Ich würde mich freuen, wenn Sie einen Blick darauf werfen könnten. stackoverflow.com/questions/32615466/…
mmm
Diese Antwort ist nicht vollständig korrekt. 'x == true' gilt nicht für Zahlen ungleich Null.
Teemoh
@ Teemoh - Ich verstehe deinen Kommentar nicht. Siehe jsfiddle.net/jfriend00/89h8d8tm .
jfriend00
1
Ich möchte nur sagen, dass 'if (x)' nicht dasselbe ist wie 'if (x == true)', wie Sie im ersten Absatz Ihrer Antwort geschrieben haben. 'if (x)' konvertiert 'x' explizit in seine boolesche Darstellung. 'if (x == true)' verwendet den EcmaScript Abstract Compare-Algorithmus. Sie haben geschrieben, dass 'if (x == true)' für jede Zahl ungleich Null, jede nicht leere Zeichenfolge oder jedes Objekt wahr ist. Das ist einfach falsch. Wenn ich Ihr Beispiel mit 2 anstelle von 1 ausführe, funktioniert es nicht.
Teemoh
2
@ Teemoh - ich verstehe deinen Standpunkt. Die Antwort wurde korrigiert und geklärt, und ich habe einen Abschnitt über Typenzwang mit einem Beispiel hinzugefügt, das zeigt, wie unerwartete Dinge geschehen können.
jfriend00
40

Wenn Sie schreiben : if(x === true), gilt dies nur für x = true

Wenn Sie schreiben if(x):, gilt dies für jedes x , das nicht: '' (leere Zeichenfolge), false, null, undefined, 0, NaN ist.

Karaxuna
quelle
(leere Zeichenfolge), false, null, undefined, 0, NaN
Oliboy50
Vergiss nicht NaNund -0.
Haykam
8

Im einfachen "if" wird die Variable zu einem Booleschen Wert gezwungen und verwendet toBoolean für das Objekt: -

    Argument Type   Result

    Undefined       false
    Null            false
    Boolean         The result equals the input argument (no conversion).
    Number          The result is false if the argument is +0, 0, or NaN;
                    otherwise the result is true.
    String          The result is false if the argument is the empty 
                    String (its length is zero); otherwise the result is true.
    Object          true.

Der Vergleich mit === hat jedoch keinen Zwang, daher müssen sie ohne Zwang gleich sein.

Wenn Sie sagen, dass das Objekt möglicherweise nicht einmal ein Boolescher Wert ist, müssen Sie möglicherweise mehr als nur wahr / falsch berücksichtigen.

if(x===true){
...
} else if(x===false){
....
} else {
....
}
QuentinUK
quelle
5

Es hängt von Ihrem Anwendungsfall ab. Es mag sinnvoll sein, den Typ ebenfalls zu überprüfen, aber wenn es nur ein Flag ist, ist dies nicht der Fall.

Ven
quelle
Der ===Vergleich führt keinen Typzwang durch. Der OP-Code testet also effektiv den Typ des Flags. Dies ist nur erfolgreich, wenn der Wert ein Boolescher Wert ist und true ist.
Jesse Hallett
Lassen Sie mich umformulieren. Wenn Sie wissen, dass es entweder wahr oder falsch sein wird, spielt es keine Rolle.
Ven
5

Im Allgemeinen ist es sauberer und einfacher, das wegzulassen === true.

In Javascript sind diese Aussagen jedoch unterschiedlich.

if (booleanValue)ausgeführt wird , wenn booleanValueist truthy - etwas anderes als 0, false, '', NaN, null, und undefined.

if (booleanValue === true)wird nur ausgeführt, wenn booleanValuegenau gleich ist true.

SLaks
quelle
Genau darauf möchte ich achten, auch wenn ich nur möchte, dass boolValue wahr oder falsch ist. Die Variable wird im Code mehrmals auf true / false gesetzt. Ich weiß das, wenn ich den Code schreibe, aber wenn ich den Code ein Jahr später noch einmal überprüfe, ist es nur ein großes Fragezeichen, wenn ich nicht alles richtig lese?
DirkZz
@aldanux: Ups; Ich meinte ''.
SLaks
4

Der Identitätsoperator (===)verhält sich identisch zur Gleichheit(==) , außer dass keine Typkonvertierung durchgeführt wird und die Typen identisch sein müssen, um als gleich zu gelten.

Apollo-SOFTWARE
quelle
Dein letzter Satz ist falsch. Probieren Sie Ihre beiden Aussagen aus if (booleanValue)und if (booleanValue==true)wann booleanValueist 2. Diese beiden Aussagen führen nicht zum gleichen Ergebnis.
jfriend00
Interessant. Ich werde dich beim Wort nehmen. Ich habe in der ObjC / C / C ++ - Welt gedacht, in JS gehe ich davon aus, dass Sie korrekt sind, da Datentypen in JS geändert werden können und 2 == true das Wenn dann nicht quantifiziert.
Apollo SOFTWARE
1
Siehe meine Antwort oben für dieses spezielle Beispiel. Dies hängt damit zusammen, wie Javascript die automatische Typkonvertierung durchführt, um zwei Werte unterschiedlicher Typen zu vergleichen.
jfriend00
3

Da der überprüfte Wert Booleanbevorzugt wird, wird er direkt für weniger Codierung verwendet, und es wurde überhaupt dasselbe getan==true

Alyafey
quelle
2

Da Sie bereits eindeutig als Bool initialisiert haben, ist der ===Operator meines Erachtens nicht erforderlich.

Sonnig
quelle
2

Wenn die Variable immer nur boolesche Werte annehmen kann, ist es sinnvoll, die kürzere Syntax zu verwenden.

Wenn es möglicherweise anderen Typen zugewiesen werden kann und Sie truevon 1oder unterscheiden "foo"müssen, müssen Sie verwenden === true.

Barmar
quelle
2

Ich denke, dass Ihre Argumentation stichhaltig ist. In der Praxis habe ich jedoch festgestellt, dass es weitaus üblicher ist, den ===Vergleich wegzulassen . Ich denke, dass es dafür drei Gründe gibt:

  1. Normalerweise wird die Bedeutung des Ausdrucks nicht erhöht - dies ist in Fällen der Fall, in denen der Wert ohnehin als boolesch bekannt ist.
  2. Da JavaScript eine große Typunsicherheit aufweist, kann das Erzwingen einer Typprüfung Sie beißen, wenn Sie ein Unerwartetes undefinedoder einen nullWert erhalten. Oft möchten Sie nur, dass Ihr Test in solchen Fällen fehlschlägt. (Obwohl ich versuche, diese Ansicht mit dem Motto "schnell scheitern" in Einklang zu bringen).
  3. JavaScript-Programmierer spielen gerne schnell und locker mit Typen - insbesondere in booleschen Ausdrücken - weil wir das können.

Betrachten Sie dieses Beispiel:

var someString = getInput();
var normalized = someString && trim(someString);  
// trim() removes leading and trailing whitespace

if (normalized) {
    submitInput(normalized);
}

Ich denke, dass diese Art von Code nicht ungewöhnlich ist. Es behandelt Fälle, in denen getInput()Retouren undefined,null , oder eine leere Zeichenfolge. Aufgrund der beiden booleschen AuswertungensubmitInput() wird nur aufgerufen, wenn die angegebene Eingabe eine Zeichenfolge ist, die Nicht-Leerzeichen enthält.

In JavaScript wird &&das erste Argument zurückgegeben, wenn es falsch ist, oder das zweite Argument, wenn das erste Argument wahr ist. so normalizedwird es sein undefinedwennsomeString es undefiniert war und so weiter. Das bedeutet, dass keine der Eingaben in die obigen booleschen Ausdrücke tatsächlich boolesche Werte sind.

Ich weiß, dass viele Programmierer, die an eine starke Typprüfung gewöhnt sind, zusammenzucken, wenn sie Code wie diesen sehen. Beachten Sie jedoch, dass beim Anwenden einer starken Typisierung wahrscheinlich explizite Überprüfungen nulloder undefinedWerte erforderlich sind, wodurch der Code unübersichtlich wird. In JavaScript wird das nicht benötigt.

Jesse Hallett
quelle
1

Das hängt davon ab. Wenn Sie befürchten, dass Ihre Variable als TRUE aufgelöst werden könnte. Dann ist eine harte Prüfung ein Muss. Ansonsten liegt es an Ihnen. Ich bezweifle jedoch, dass die Syntax whatever == TRUEjemals jemanden verwirren würde, der wusste, was er tat.

usumoio
quelle
1

In Javascript ist die Idee des Booleschen Wertes ziemlich vieldeutig. Bedenken Sie:

 var bool = 0 
 if(bool){..} //evaluates to false

 if(//uninitialized var) //evaluates to false

Wenn Sie also eine if-Anweisung (oder eine andere Steueranweisung) verwenden, muss keine var-Typ vom Typ "Boolean" verwendet werden. Daher ist meiner Meinung nach der Teil "=== true" Ihrer Aussage nicht erforderlich, wenn Sie wissen, dass es sich um einen Booleschen Wert handelt, aber absolut notwendig, wenn Ihr Wert eine mehrdeutige "wahrheitsgemäße" Variable ist. Mehr zu Booleschen Werten in Javscript finden Sie hier .

RestingRobot
quelle
1

Kann auch mit einem Booleschen Objekt getestet werden, wenn Sie ein Objekt testen müssen error={Boolean(errors.email)}

Igor Pavlenko
quelle