JavaScript führt seine Vorfahren auf C zurück, und C hat keinen logischen XOR-Operator. Hauptsächlich, weil es nicht nützlich ist. Bitweises XOR ist äußerst nützlich, aber in all meinen Jahren der Programmierung habe ich nie ein logisches XOR benötigt.
Wenn Sie zwei boolesche Variablen haben, können Sie XOR nachahmen mit:
if (a != b)
Mit zwei beliebigen Variablen können Sie !
sie zu booleschen Werten zwingen und dann denselben Trick anwenden:
if (!a != !b)
Das ist allerdings ziemlich dunkel und würde sicherlich einen Kommentar verdienen. In der Tat könnten Sie an dieser Stelle sogar den bitweisen XOR-Operator verwenden, obwohl dies für meinen Geschmack viel zu klug wäre:
if (!a ^ !b)
!=
ist, dass Sie nicht dasselbe tun können wiea ^= b
, weila !== b
es sich nur um den strengen Ungleichungsoperator handelt .Javascript hat einen bitweisen XOR-Operator: ^
Sie können es mit Booleschen Werten verwenden und das Ergebnis wird als 0 oder 1 angegeben (die Sie beispielsweise wieder in Boolesche Werte konvertieren können
result = !!(op1 ^ op2)
). Aber wie John sagte, ist es gleichbedeutend mitresult = (op1 != op2)
, was klarer ist.quelle
true^true
ist 0 undfalse^true
ist 1.||
und&&
kann als logischer Operator für Nicht-Boolesche Werte verwendet werden (z. B.5 || 7
gibt einen wahrheitsgemäßen Wert zurück,"bob" && null
gibt einen falschen Wert zurück),^
kann dies jedoch nicht. Zum Beispiel ist5 ^ 7
2 gleich, was wahr ist.(true ^ false) !== true
was es ärgerlich macht mit Bibliotheken, die tatsächliche Booleschea ^= true
um Boolesche Werte umzuschalten, und es schlägt auf einigen Computern wie Telefonen fehl.Es gibt keine echten logischen booleschen Operatoren in Javascript (obwohl dies
!
ziemlich nahe kommt). Ein logischer Operator würde nurtrue
oderfalse
als Operanden nehmen und nurtrue
oder zurückgebenfalse
.In Javascript
&&
und||
nimmt alle Arten von Operanden und liefert alle Arten lustiger Ergebnisse (was auch immer Sie in sie zu füttern).Auch ein logischer Operator sollte immer die Werte beider Operanden berücksichtigen.
In Javascript
&&
und||
nimmt eine faule Verknüpfung und nicht nicht bewertet die zweiten Operanden in bestimmten Fällen und damit Vernachlässigung ihrer Nebenwirkungen. Dieses Verhalten kann mit einem logischen xor nicht wiederhergestellt werden.a() && b()
werteta()
das Ergebnis aus und gibt es zurück, wenn es falsch ist. Andernfalls wirdb()
das Ergebnis ausgewertet und zurückgegeben. Daher ist das zurückgegebene Ergebnis wahr, wenn beide Ergebnisse wahr sind, und ansonsten falsch.a() || b()
werteta()
das Ergebnis aus und gibt es zurück, wenn es wahr ist. Ansonsten wird ausgewertetb()
das Ergebnis und zurückgegeben. Daher ist das zurückgegebene Ergebnis falsch, wenn beide Ergebnisse falsch sind, und ansonsten wahr.Die allgemeine Idee ist also, zuerst den linken Operanden auszuwerten. Der richtige Operand wird nur bei Bedarf ausgewertet. Und der letzte Wert ist das Ergebnis. Dieses Ergebnis kann alles sein. Objekte, Zahlen, Strings ... was auch immer!
Dies macht es möglich, Dinge wie zu schreiben
oder
Der Wahrheitswert dieses Ergebnisses kann aber auch verwendet werden, um zu entscheiden, ob ein "echter" logischer Operator wahr oder falsch zurückgegeben hätte.
Dies macht es möglich, Dinge wie zu schreiben
oder
Ein "logischer" xor-Operator (
^^
) müsste jedoch immer beide Operanden auswerten. Dies unterscheidet es von den anderen "logischen" Operatoren, die den zweiten Operanden nur bei Bedarf auswerten. Ich denke, aus diesem Grund gibt es in Javascript kein "logisches" xor, um Verwirrung zu vermeiden.Was soll also passieren, wenn beide Operanden falsch sind? Beide konnten zurückgegeben werden. Es kann jedoch nur einer zurückgegeben werden. Welcher? Der erste? Oder der zweite? Meine Intuition sagt mir, dass ich die ersten, aber normalerweise "logischen" Operatoren von links nach rechts auswerten und den zuletzt ausgewerteten Wert zurückgeben soll. Oder vielleicht ein Array, das beide Werte enthält?
Und wenn ein Operand wahr und der andere falsch ist, sollte ein xor den wahrheitsgemäßen zurückgeben. Oder vielleicht ein Array, das das Wahrhafte enthält, um es mit dem vorherigen Fall kompatibel zu machen?
Und schließlich, was soll passieren, wenn beide Operanden wahr sind? Sie würden etwas Falsches erwarten. Es gibt jedoch keine falschen Ergebnisse. Die Operation sollte also nichts zurückgeben. Also vielleicht
undefined
oder ... ein leeres Array? Aber ein leeres Array ist immer noch wahr.Wenn Sie den Array-Ansatz wählen, erhalten Sie Bedingungen wie
if ((a ^^ b).length !== 1) {
. Sehr verwirrend.quelle
Das XOR zweier Boolescher Werte ist einfach, ob sie unterschiedlich sind, daher:
quelle
Konvertieren Sie Werte in eine boolesche Form und nehmen Sie dann bitweises XOR an. Es hilft auch bei nicht-booleschen Werten.
quelle
Verdeckt auf Boolesch und führe dann xor like - aus
quelle
!!a ^ !!b
äquivalent zu ist!a ^ !b
. Es könnten Argumente vorgebracht werden, die leichter zu lesen sind.es gibt ... irgendwie:
oder leichter zu lesen:
Warum? Keine Ahnung.
weil Javascript-Entwickler dachten, es wäre unnötig, da es von anderen, bereits implementierten logischen Operatoren ausgedrückt werden kann.
Sie könnten genauso gut mit nand gon haben und das ist es, Sie können jede andere mögliche logische Operation davon beeindrucken.
Ich persönlich denke, es hat historische Gründe, die von c-basierten Syntaxsprachen herrühren, bei denen meines Wissens xor nicht vorhanden oder zumindest äußerst ungewöhnlich ist.
quelle
Ja, machen Sie einfach Folgendes. Angenommen, Sie haben es mit den Booleschen Werten A und B zu tun, kann der Wert A XOR B in JavaScript wie folgt berechnet werden
Die vorherige Zeile entspricht auch der folgenden
Persönlich bevorzuge ich xor1, da ich weniger Zeichen eingeben muss. Ich glaube, dass xor1 auch schneller ist. Es werden nur zwei Berechnungen durchgeführt. xor2 führt drei Berechnungen durch.
Visuelle Erklärung ... Lesen Sie die folgende Tabelle (wobei 0 für falsch und 1 für wahr steht) und vergleichen Sie die 3. und 5. Spalte.
! (A === B):
Genießen.
quelle
var xor1 = !(a === b);
ist das gleiche wievar xor1 = a !== b;
!(2 === 3)
isttrue
, aber2
und3
sind wahr, so2 XOR 3
sollte es seinfalse
.Auschecken:
Sie können es so etwas nachahmen:
quelle
Wie wäre es, das Ergebnis int in einen Bool mit doppelter Negation umzuwandeln ? Nicht so hübsch, aber sehr kompakt.
quelle
B = ((!state1)!==(!state2))
B =!!(!state1 ^ !state2);
Warum auch so viele Klammern?B = !state1 !== !state2;
Oder Sie können sogar die Negation fallen lassen:B = state1 !== state2;
state1 !== state2
, müssen Sie dort kein Casting durchführen, da!==
es sich um einen logischen Operator handelt, nicht um einen bitweisen.12 !== 4
ist wahr'xy' !== true
ist auch wahr. Wenn Sie!=
anstelle von verwenden würden!==
, müssten Sie Casting durchführen.!==
und!=
ist immer boolesch ... nicht sicher, welche Unterscheidung Sie dort machen sollen, das ist absolut nicht das Problem. Das Problem ist, dass der gewünschte XOR-Operator wirklich der Ausdruck ist(Boolean(state1) !== Boolean(state2))
. Für Boolesche Werte sind "xy", 12, 4 undtrue
alle wahrheitsgemäße Werte und sollten in konvertiert werdentrue
. so("xy" XOR true)
sollte es seinfalse
, ist es aber("xy" !== true)
stattdessentrue
, wie Sie betonen. Also!==
oder!=
sind (beide) gleichbedeutend mit "logischem XOR", wenn und nur wenn Sie ihre Argumente vor dem Anwenden in Boolesche Werte konvertieren .In der obigen xor-Funktion ergibt sich ein ähnliches Ergebnis, da logisches xor nicht genau logisches xor ist, was bedeutet, dass es "falsch für gleiche Werte" und "wahr für verschiedene Werte" ergibt, wobei die Datentypübereinstimmung berücksichtigt wird.
Diese XOR - Funktion funktioniert als tatsächliche xor oder logischer Operator , Mittel wird es wahr oder falsch gemäß Ergebnis an die Weitergabe Werte sind truthy oder falsy . Verwenden Sie nach Ihren Bedürfnissen
quelle
(!!x) === (!!y)
. Der Unterschied ist eine Umwandlung in Boolesche Werte.'' === 0
ist falsch, währendxnor('', 0)
wahr ist.In Typescript (Das + ändert sich in einen numerischen Wert):
So:
quelle
!!(false ^ true)
funktioniert gut mit Booleschen Werten. In Typoskript ist + erforderlich, um es gültig zu machen!!(+false ^ +true)
.cond1 xor cond2
ist äquivalent zucond1 + cond 2 == 1
:Hier ist der Beweis:
quelle
Der Grund, warum es kein logisches XOR (^^) gibt, liegt im Gegensatz zu && und || es gibt keinen faulen logischen Vorteil. Das ist der Zustand beider Ausdrücke rechts und links, die ausgewertet werden müssen.
quelle
Hier ist eine alternative Lösung, die mit 2+ Variablen arbeitet und als Bonus zählt.
Hier ist eine allgemeinere Lösung, um logisches XOR für alle Wahrheits- / False-Werte zu simulieren, als hätten Sie den Operator in Standard-IF-Anweisungen:
Der Grund, warum ich das mag, ist, dass es auch antwortet "Wie viele dieser Variablen sind wahr?", Also speichere ich dieses Ergebnis normalerweise vor.
Und für diejenigen, die ein striktes boolesches-WAHRES xor-Überprüfungsverhalten wünschen, tun Sie einfach:
Wenn Sie sich nicht für die Zählung interessieren oder wenn Sie sich für eine optimale Leistung interessieren: Verwenden Sie einfach das bitweise xor für Werte, die zu Booleschen Werten gezwungen werden, um die Lösung für Wahrheit / Falschheit zu erhalten:
quelle
Hey, ich habe diese Lösung gefunden, um und XOR auf JavaScript und TypeScript zu machen.
quelle
Probieren Sie diese kurze und leicht verständliche aus
Dies funktioniert für jeden Datentyp
quelle
true == someboolean
nicht erforderlich. Sie haben also die strengen Ungleichheiten in eine Funktion eingewickelt.