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 gesehen, nicht so wichtig, um herauszufinden, ob eine einzelne Variable (oder sogar mehrere Variablen) wahr oder falsch ist. !!myVar === true
ist dasselbe wie nur myVar
. Vergleich von !!X
in einen "echten" Booleschen Wert umzuwandeln, ist nicht wirklich nützlich.
Das Einzige, was Sie gewinnen, wenn Sie !!
ist die Fähigkeit, den Wahrheitsgehalt mehrerer Variablen zu überprüfen gegeneinander in einer wiederholbaren, standardisierten (und JSLint-freundlichen) Weise.
Einfach gießen :(
Das heißt...
0 === false
es false
.
!!0 === false
es true
.
Die obigen Angaben sind nicht so nützlich. if (!0)
liefert die gleichen Ergebnisse wie if (!!0 === false)
. Mir fällt kein guter Grund ein, eine Variable in einen booleschen Wert umzuwandeln und dann mit einem booleschen Wert "true" zu vergleichen.
Siehe "== und !=" aus JSLint's Wegbeschreibung (Anmerkung: Crockford ist dabei, seine Website ein wenig zu verschieben; dieser Link wird wahrscheinlich irgendwann verschwinden), um ein wenig über die Gründe zu erfahren:
Die Operatoren == und != führen vor dem Vergleich eine Typenzerlegung durch. Das ist schlecht, denn es verursacht ' \t\r\n ' == 0 wahr sein. 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 benutzen.
Wenn es Ihnen nur darum geht, ob ein Wert wahr oder falsch ist, dann verwenden Sie die Kurzform. Anstelle von
(foo != 0)
nur sagen
(foo)
und anstelle von
(foo == 0)
sagen
(!foo)
Beachten Sie, dass es einige unintuitive Fälle wobei ein boolescher Wert in eine Zahl umgewandelt wird ( true
wird geworfen auf 1
y false
a 0
), wenn ein boolescher Wert mit einer Zahl verglichen wird. In diesem Fall, !!
geistig nützlich sein könnte. Obwohl, noch einmal, Dies sind Fälle, in denen Sie einen Nicht-Booleschen mit einem hart getippten Booleschen vergleichen, was imo ein schwerer Fehler ist. if (-1)
ist hier nach wie vor der richtige Weg.
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 werden die Dinge noch verrückter. WScript, zum Beispiel, gewinnt den Preis.
function test()
{
return (1 === 1);
}
WScript.echo(test());
Wegen der einige historische Windows-Sprüche wird in einem Nachrichtenfeld -1 ausgegeben! Versuchen Sie es in einer cmd.exe-Eingabeaufforderung und sehen Sie nach! Aber WScript.echo(-1 == test())
ergibt immer noch 0, oder WScripts false
. Schauen Sie weg. Es ist abscheulich.
Wahrhaftigkeit im Vergleich :)
Was aber, wenn ich zwei Werte habe, die ich auf gleiche Wahrhaftigkeit/Falschheit prüfen muss?
Nehmen wir an, wir haben myVar1 = 0;
y myVar2 = undefined;
.
myVar1 === myVar2
es 0 === undefined
und ist offensichtlich falsch.
!!myVar1 === !!myVar2
es !!0 === !!undefined
und ist wahr! Gleiche Wahrhaftigkeit! (In diesem Fall haben beide "einen Wahrheitsgehalt von falsy".)
Der einzige Ort, an dem Sie wirklich "boolesche Variablen" verwenden müssten, wäre eine Situation, in der Sie prüfen, ob beide Variablen die dieselbe Wahrhaftigkeit, richtig? Das heißt, utiliser !!
wenn Sie sehen müssen, ob zwei Variablen gleich sind beide wahrheitsgemäß oder beide falsch (oder nicht), das heißt, von gleicher (oder auch nicht) Wahrhaftigkeit .
Mir fällt auf Anhieb kein großartiger, ungekünstelter Anwendungsfall dafür ein. Vielleicht haben Sie "verknüpfte" Felder in einem Formular?
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 haben o ein falsches Feld für den Namen des Ehepartners und das Alter, können Sie fortfahren. Andernfalls haben Sie nur ein Feld mit einem Wert (oder eine sehr früh arrangierte Ehe) und müssen einen zusätzlichen Fehler in Ihrer errorObjects
Sammlung.
Aber auch in diesem Fall ist die !!
ist wirklich überflüssig. Eine !
genügte, um in einen Booleschen Wert umzuwandeln, und Sie prüfen nur die Gleichheit.
EDIT 24 Oct 2017, 6 Feb 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.
Reagieren Sie
Zum Beispiel, False in JSX (React) hat eine besondere Bedeutung die nicht durch einfache Falschheit ausgelöst wird. Wenn Sie versucht, die Rückgabe etwas wie das folgende in Ihrem JSX, erwarten eine int in messageCount
...
{messageCount && <div>You have messages!</div>}
... werden Sie vielleicht überrascht sein, dass React eine 0
wenn Sie keine Nachrichten haben. Sie müssen explizit false zurückgeben, damit JSX nicht gerendert wird. Die obige Anweisung gibt 0
die JSX fröhlich wiedergibt, wie es sich gehört. Es kann nicht sagen, dass Sie nicht haben Count: {messageCount}
.
-
Eine Lösung ist der "Bangbang", der die Menschen dazu zwingt 0
in !!0
que es false
:
{!!messageCount && <div>You have messages!</div>}
-
JSX' docs empfehlen Sie expliziter sein, schreiben selbst-kommentierenden Code, und verwenden Sie einen Vergleich zu einem Boolean zu erzwingen.
{messageCount > 0 && <div>You have messages!</div>}
-
Ich selbst komme mit Falschheit besser zurecht, wenn ich eine ternäre --
{messageCount ? <div>You have messages!</div> : false}
Typoskript
Dasselbe gilt für Typescript: Wenn Sie eine Funktion haben, die einen booleschen Wert zurückgibt (oder Sie weisen einer booleschen Variablen einen Wert zu), können Sie [normalerweise] keinen booleschen Wert zurückgeben/zuweisen; es muss ein stark typisierter boolescher Wert sein. Dies bedeutet, wenn myObject
stark typisiert ist , return !myObject;
funktioniert für eine Funktion, die einen booleschen Wert zurückgibt, aber return myObject;
nicht. Sie müssen return !!myObject
(oder auf andere Weise in den richtigen Booleschen Wert umwandeln), um die Erwartungen von Typescript zu erfüllen.
Die Ausnahme für Typescript? Wenn myObject
war ein any
sind Sie zurück im Wilden Westen von JavaScript und können es ohne !!, even if your return type is a boolean.
``
Keep in mind that these are JSX & Typescript conventions, not ones inherent to JavaScript.
But if you see strange 0
s in your rendered JSX, think loose falsy management.
``
1428 Stimmen
Erinnern Sie sich daran mit "bang, bang, du bist boolesch"
126 Stimmen
Nur um das festzuhalten: Tun Sie nicht, was dort steht. Machen Sie
if(vertical !== undefined) this.vertical = Boolean(vertical);
- es ist viel sauberer und klarer, was vor sich geht, erfordert keine unnötige Zuweisung, ist ganz Standard und ist genauso schnell (auf aktuellem FF und Chrome) jsperf.com/boolean-conversion-speed .0 Stimmen
"Jeder anständige Programmierer sollte wissen, was vor sich geht..." - manchmal hilft es dem Compiler, besseren Code in kompilierten Sprachen zu erzeugen. Ich weiß, dass es früher von Microsoft bei der Verwendung von C-Code empfohlen wurde, weil es den besten Code erzeugt. (Wahrscheinlich wird es immer noch empfohlen, aber ich kann die Referenz im Moment nicht finden).
127 Stimmen
!! ist kein Operator. Es ist nur der Operator ! zweimal.
85 Stimmen
@schabluk, fürs Protokoll, Reihenfolge der Operationen ist der Grund
!!5/0
produziertInfinity
statttrue
wie sie vonBoolean(5/0)
.!!5/0
ist gleichbedeutend mit(!!5)/0
-auch bekannt alstrue/0
-- aufgrund der!
Operator, der einen höheren Vorrang hat als der/
Betreiber. Wenn Sie die Booleschen Operatoren5/0
Wenn Sie einen Doppelknall verwenden, müssen Sie!!(5/0)
.0 Stimmen
Einfach ausgedrückt: !!vertical gibt Ihnen einen booleschen Wert, der angibt, ob "vertikal" definiert oder nicht-falsch ist.
2 Stimmen
Was bedeutet !!(x) in C (vor allem im Linux-Kernel)?
0 Stimmen
Nur fürs Protokoll: Boolean(5/0) ist nicht dasselbe wie !!5/0 - schabluk 12. Februar '15 um 9:45 Ja, weil Sie die zweite Anweisung ohne die Klammern verwenden. In jedem anderen Fall sind sie dasselbe Boolean(5/0) dasselbe wie !!(5/0)
2 Stimmen
Erklären Sie einfach:
!!value === Boolean(value)
52 Stimmen
@Gus Nur damit du es weißt: Ich habe deinen Kommentar schon 2012 gelesen. In den 7 Jahren, die seitdem vergangen sind, habe ich im Geiste immer gesagt: "Peng, peng, du bist ein Boolescher!", wenn ich einen Booleschen Wert invertiert habe, und ich habe mich immer daran erinnert, wie das geht. Ich habe heute beschlossen, Ihren Kommentar nachzuschlagen und Ihnen Bescheid zu geben :-)
11 Stimmen
@ZacharySchuessler thx, ich freue mich, dass es so vielen gefällt, und ich habe sogar gesehen, dass es jetzt in Tutorial-Seiten und so zitiert (und gutgeschrieben) wird, was großartig ist :) ich hätte mir nie träumen lassen, dass ich eine so beliebte Eselsbrücke prägen würde.
0 Stimmen
Phil H BTW in javascript sollte man eine Variable nicht mit dem ternären Operator (!== oder ===) prüfen. Verwenden Sie einfach (Variable == null). Die Überprüfung einer Variablen mit dem ternären Operator bedeutet, dass Sie sowohl undefined als auch null überprüfen müssen. In javascript (OP-Abfrage) undefined !== null
0 Stimmen
Wenn this.vertical == "good" und vertical == "other", dann würde this.vertical in einen booleschen Wert true!! geändert werden. Das ist nicht deterministisch. Dieser Code ändert einfach den Variablentyp, was zu unerwarteten Ergebnissen führen wird
0 Stimmen
Ich betrachte es als eine Art "Wahrheits-Check".
0 Stimmen
Wird die Variable einfach gezwungen, einen booleschen Wert zu haben. Dies ist nützlich für Assertions und Prüfungen.