Brühen Sie einen Tee auf:
!!
ist kein Operator. Es ist die doppelte Verwendung von !
-- das ist der logische "nicht"-Operator.
Theoretisch:
!
bestimmt die "Wahrheit" dessen, was ein Wert nicht ist:
-
Die Wahrheit ist, dass false
no es true
(deshalb !false
Ergebnisse in true
)
-
Die Wahrheit ist, dass true
no es false
(deshalb !true
Ergebnisse in false
)
!!
bestimmt die "Wahrheit" dessen, was ein Wert ist no nicht:
-
Die Wahrheit ist, dass true
no es no true
(deshalb !!true
führt zu true
)
-
Die Wahrheit ist, dass false
no es no false
(deshalb !!false
führt zu false
)
Was wir mit dem Vergleich feststellen wollen, ist die "Wahrheit". über den Wert einer Referenz, nicht den Wert von die Referenz selbst. Es gibt einen Anwendungsfall, in dem wir die Wahrheit über einen Wert wissen wollen, selbst wenn wir erwarten, dass der Wert false
(oder falsch), oder wenn wir erwarten, dass der Wert nicht typeof ist boolean
.
In der Praxis:
Betrachten wir eine prägnante Funktion, die die Funktionalität eines Merkmals (und in diesem Fall die Plattformkompatibilität) mit Hilfe von dynamische Schreibweise (auch bekannt als "Duck-Typing"). Wir wollen eine Funktion schreiben, die Folgendes zurückgibt true
wenn der Browser eines Nutzers die HTML5 <audio>
Element, aber wir wollen nicht, dass die Funktion einen Fehler auslöst, wenn <audio>
undefiniert ist; und wir wollen nicht mit try ... catch
um mit möglichen Fehlern umzugehen (weil sie grob sind); und auch wir wollen keine Prüfung innerhalb der Funktion verwenden, die nicht konsequent die Wahrheit über das Merkmal aufdeckt (z. B., document.createElement('audio')
wird weiterhin ein Element namens <audio>
auch wenn HTML5 <audio>
wird nicht unterstützt).
Hier sind die drei Ansätze:
// this won't tell us anything about HTML5 `<audio>` as a feature
var foo = function(tag, atr) { return document.createElement(tag)[atr]; }
// this won't return true if the feature is detected (although it works just fine)
var bar = function(tag, atr) { return !document.createElement(tag)[atr]; }
// this is the concise, feature-detecting solution we want
var baz = function(tag, atr) { return !!document.createElement(tag)[atr]; }
foo('audio', 'preload'); // returns "auto"
bar('audio', 'preload'); // returns false
baz('audio', 'preload'); // returns true
Jede Funktion akzeptiert ein Argument für eine <tag>
und ein attribute
nach denen sie suchen, aber sie geben jeweils unterschiedliche Werte zurück, je nachdem, was die Vergleiche ergeben.
Aber halt, es gibt noch mehr!
Einige von Ihnen haben wahrscheinlich bemerkt, dass man in diesem speziellen Beispiel einfach nach einer Eigenschaft suchen könnte, indem man die leicht leistungsfähiger Mittel zur Überprüfung, ob das betreffende Objekt hat eine Eigenschaft. Es gibt zwei Möglichkeiten, dies zu tun:
// the native `hasOwnProperty` method
var qux = function(tag, atr) { return document.createElement(tag).hasOwnProperty(atr); }
// the `in` operator
var quux = function(tag, atr) { return atr in document.createElement(tag); }
qux('audio', 'preload'); // returns true
quux('audio', 'preload'); // returns true
Wir schweifen ab...
Wie selten diese Situationen auch sein mögen, so gibt es doch einige wenige Szenarien, in denen das prägnanteste, leistungsfähigste und somit bevorzugte Mittel, um true
von einem nicht-booleschen, möglicherweise undefinierten Wert ist in der Tat durch die Verwendung von !!
. Ich hoffe, das klärt die Sache lächerlich auf.
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.