So viele Antworten machen die halbe Arbeit. Ja, !!X
könnte als "die Wahrhaftigkeit von X [dargestellt als Boolescher Wert]" gelesen werden. Aber !!
ist praktisch nicht so wichtig, um herauszufinden, ob eine einzelne Variable wahr oder falsch ist (oder auch wenn viele Variablen wahr sind). !!myVar === true
ist das gleiche wie gerade myVar
. Der Vergleich !!X
mit einem "echten" Booleschen Wert ist nicht wirklich nützlich.
Was Sie damit gewinnen, !!
ist die Fähigkeit, die Richtigkeit mehrerer Variablen gegeneinander zu prüfen auf wiederholbare, standardisierte (und JSLint-freundliche) Weise .
Einfach gießen :(
Das ist...
0 === false
ist false
.
!!0 === false
ist true
.
Das obige ist nicht so nützlich. if (!0)
gibt Ihnen die gleichen Ergebnisse wie if (!!0 === false)
. Ich kann mir keinen guten Fall vorstellen, um eine Variable in einen Booleschen Wert umzuwandeln und dann mit einem "wahren" Booleschen Wert zu vergleichen.
Siehe "== und! =" Aus den Anweisungen von JSLint (Hinweis: Crockford verschiebt seine Website ein wenig; dieser Link kann irgendwann sterben) für ein wenig warum:
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.
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)
Beachten Sie, dass es einige nicht intuitive Fälle gibt, in denen ein Boolescher Wert in eine Zahl umgewandelt wird ( true
in 1
und false
nach 0
), wenn ein Boolescher Wert mit einer Zahl verglichen wird. In diesem Fall !!
könnte geistig nützlich sein. Obwohl wieder, diese Fälle , in denen Sie ein nicht-boolean zu einem harten typisierte boolean sind zu vergleichen, das ist, imo, ein schwerwiegender Fehler. if (-1)
ist immer noch der Weg hierher.
╔═══════════════════════════════════════╦═══════════════════╦═══════════╗
║ Original ║ Equivalent ║ Result ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1 == true) console.log("spam") ║ if (-1 == 1) ║ undefined ║
║ if (-1 == false) console.log("spam") ║ if (-1 == 0) ║ undefined ║
║ Order doesn't matter... ║ ║ ║
║ if (true == -1) console.log("spam") ║ if (1 == -1) ║ undefined ║
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (!!-1 == true) console.log("spam") ║ if (true == true) ║ spam ║ better
╠═══════════════════════════════════════╬═══════════════════╬═══════════╣
║ if (-1) console.log("spam") ║ if (truthy) ║ spam ║ still best
╚═══════════════════════════════════════╩═══════════════════╩═══════════╝
Und je nach Motor wird es noch verrückter. WScript zum Beispiel gewinnt den Preis.
function test()
{
return (1 === 1);
}
WScript.echo(test());
Aufgrund eines historischen Windows-Jives wird -1 in einem Meldungsfeld ausgegeben! Versuchen Sie es in einer cmd.exe-Eingabeaufforderung und sehen Sie! Aber WScript.echo(-1 == test())
gibt Ihnen immer noch 0 oder WScript false
. Schau weg. Es ist schrecklich.
Wahrhaftigkeit vergleichen :)
Aber was ist, wenn ich zwei Werte habe, die ich auf gleiche Wahrheit / Falschheit prüfen muss?
Stellen Sie sich vor, wir hätten myVar1 = 0;
und myVar2 = undefined;
.
myVar1 === myVar2
ist 0 === undefined
und ist offensichtlich falsch.
!!myVar1 === !!myVar2
ist !!0 === !!undefined
und ist wahr! Gleiche Wahrhaftigkeit! (In diesem Fall haben beide "eine Wahrheit der Falschheit".)
Der einzige Ort, an dem Sie wirklich "boolesche Cast-Variablen" verwenden müssten, wäre, wenn Sie eine Situation hätten, in der Sie prüfen, ob beide Variablen die gleiche Wahrhaftigkeit haben, oder? Das heißt, verwenden Sie , wenn Sie sehen müssen, ob zwei Vars beide wahr oder beide falsch (oder nicht) sind, dh von gleicher (oder nicht) Wahrhaftigkeit .!!
Ich kann mir keinen großartigen, nicht erfundenen Anwendungsfall für diese Nebenhand vorstellen. Vielleicht haben Sie Felder in einem Formular "verknüpft"?
if (!!customerInput.spouseName !== !!customerInput.spouseAge ) {
errorObjects.spouse = "Please either enter a valid name AND age "
+ "for your spouse or leave all spouse fields blank.";
}
Wenn Sie also eine Wahrheit für beide oder eine Falschheit für den Namen und das Alter des Ehepartners haben, können Sie fortfahren. Andernfalls haben Sie nur ein Feld mit einem Wert (oder einer sehr früh arrangierten Ehe) und müssen einen zusätzlichen Fehler in Ihrer errorObjects
Sammlung erstellen .
BEARBEITEN 24. Oktober 2017, 6. Februar 19:
Bibliotheken von Drittanbietern, die explizite boolesche Werte erwarten
Hier ist ein interessanter Fall ... !!
kann nützlich sein, wenn Bibliotheken von Drittanbietern explizite boolesche Werte erwarten.
Zum Beispiel hat False in JSX (React) eine besondere Bedeutung , die nicht durch einfache Falschheit ausgelöst wird. Wenn Sie versucht haben, in JSX Folgendes zurückzugeben, erwarten Sie ein int in messageCount
...
{messageCount && <div>You have messages!</div>}
... Sie könnten überrascht sein, 0
wenn React a rendert, wenn Sie keine Nachrichten haben. Sie müssen explizit false zurückgeben, damit JSX nicht gerendert wird. Die obige Anweisung gibt zurück 0
, die JSX gerne wiedergibt, wie es sollte. Es kann nicht sagen, dass Sie nicht hatten Count: {messageCount && <div>Get your count to zero!</div>}
(oder etwas weniger erfunden).
Ein Update beinhaltet die bangbang, die nötigt 0
in !!0
, das ist false
:
{!!messageCount && <div>You have messages!</div>}
In den JSX-Dokumenten wird empfohlen, expliziter zu sein, selbstkommentierenden Code zu schreiben und einen Vergleich zu verwenden, um einen Booleschen Wert zu erzwingen.
{messageCount > 0 && <div>You have messages!</div>}
Ich fühle mich wohler mit Falschheit selbst mit einem ternären -
{messageCount ? <div>You have messages!</div> : false}
Gleiches Angebot in Typescript: Wenn Sie eine Funktion haben, die einen Booleschen Wert zurückgibt (oder einer booleschen Variablen einen Wert zuweisen), können Sie [normalerweise] keinen Booleschen-y-Wert zurückgeben / zuweisen. Es muss ein stark typisierter Boolescher Wert sein. Dies bedeutet, dass iffmyObject
, wenn es stark typisiert ist , return !myObject;
für eine Funktion funktioniert, die einen Booleschen Wert zurückgibt, dies jedoch return myObject;
nicht tut. Sie müssen return !!myObject
den Erwartungen von Typescript entsprechen.
Die Ausnahme für Typescript? Wenn dies der Fall myObject
war any
, befinden Sie sich wieder im Wilden Westen von JavaScript und können es ohne zurückgeben !!
, auch wenn Ihr Rückgabetyp ein Boolescher Wert ist.
Beachten Sie, dass dies JSX- und Typescript-Konventionen sind, die JavaScript nicht eigen sind .
Aber wenn Sie seltsame 0
s in Ihrem gerenderten JSX sehen, denken Sie an lockeres Falsy-Management.