Warum gibt (0 <5 <3) true zurück?


348

Ich habe in jsfiddle.net herumgespielt und bin gespannt, warum dies wahr ist.

if(0 < 5 < 3) {
    alert("True");
}

So auch:

if(0 < 5 < 2) {
    alert("True");
}

Das geht aber nicht:

if(0 < 5 < 1) {
    alert("True");
}

Ist diese Eigenart jemals nützlich?


12
Kennen Sie wtfjs.com ?
Harmen

1
Ha! Nein, das hatte ich noch nie gesehen.
Punkrockbuddyholly

Ah, die Freuden impliziter Typkonvertierungen.
Jörg W Mittag

4
Schon mal nützlich? Möglicherweise zur Verschleierung. :-)
Icode4food

Warum? Außerdem ist alles nützlich, wenn Sie nur die Umstände finden können, die dies erfordern. Zwar wird dieser seltener benötigt als viele andere, aber es gibt Zeiten, in denen es genau das richtige Werkzeug für den Job sein kann.
temporärer_Benutzername

Antworten:


440

Die Reihenfolge der Operationen bewirkt (0 < 5 < 3), dass die Interpretation in Javascript so interpretiert wird, dass ((0 < 5) < 3)erzeugt (true < 3)und wahr als 1 gezählt wird, wodurch wahr zurückgegeben wird.

Dies ist auch der Grund (0 < 5 < 1), warum false zurückgegeben wird und (0 < 5)true zurückgegeben wird, was als interpretiert wird 1, was zu führt (1 < 1).


158
Und weil JavaScript NICHT Python ist. :-)
Rsenna

1
Sie haben geantwortet, während ich meine Frage bearbeitet habe, um die hinzuzufügen if(0 < 5 < 1) == false. Alles ist jetzt klar, danke :)
Punkrockbuddyholly

28
Genau, Python ist die einzige mir bekannte Sprache, die diese Syntax behandelt ((0 < 5) && (5 < 3)), da es wahrscheinlich andere gibt, aber ich kenne sie nicht.
Alan Geleynse

18
@ Alan: Mathematica ist ein weiteres Beispiel.
Joren

2
IMHO JavaScript sollte TypeError auslösen, wenn versucht wird, Boolesche Werte mit Zahlen zu vergleichen, da dies keinen Sinn ergibt.
Michał Perłakowski

63

Meine Vermutung ist, weil 0 < 5es wahr ist und true < 3gegossen wird, 1 < 3was wahr ist.


7
Hier gibt es kein Casting. Eine Umwandlung ist ein Operator, mit dem der Programmierer einen Typ explizit überprüft. Dies ist eine implizite Konvertierung von einem Booleschen Wert in eine Ganzzahl.
erickson

4
@erickson, wirklich ... MÜSSEN wir hier an der Semantik hängen bleiben?
CaffGeek

2
Mach dir keine Sorgen um Erickson. Ich missbrauche auch das Wort Semantik. :)
Mateen Ulhaq

9
In jedem Fall ist der richtige Begriff Zwang . Und ja, erickson ist teilweise falsch mit seiner absoluten Gewissheit. Ein Zwang ist in jedem Fall eine Art Besetzung, auch wenn Sie normalerweise (aber es ist nur eine Konvention) das Wort "Besetzung" verwenden, um explizite Typkonvertierungen auszudrücken. Typkonvertierung == Typguss.
Jack

1
Sophisten den ganzen Weg ... Die Antwort ist sowieso "lakonisch" nett;)
Arman McHitarian

21

wahrscheinlich , weil trueals angenommen , 1so

0 < 5 < 3  -->  true < 3 -->  1 < 3  --> true


10

Zu Ihrer Frage, ob diese Eigenart jemals nützlich ist: Ich nehme an, es könnte einen Fall geben, in dem sie nützlich wäre (wenn Sie nach komprimiertem Code suchen), aber wenn Sie sich darauf verlassen, wird dies (höchstwahrscheinlich) die Verständlichkeit Ihres Codes erheblich beeinträchtigen.

Es ist so, als würde man Post / Pre-Inkrement / Dekrement als Teil größerer Ausdrücke verwenden. Können Sie auf einen Blick feststellen, was das Ergebnis dieses Codes ist?

int x = 5;
int result = ++x + x++ + --x;

Hinweis: Mit diesem Code können Sie je nach Sprache und Compiler manchmal sogar unterschiedliche Ergebnisse erzielen.

Es ist eine gute Idee, sich und dem nächsten Mann, der Ihren Code liest , das Leben zu erleichtern . Schreiben Sie klar auf, was tatsächlich passieren soll, anstatt sich auf Nebenwirkungen wie die implizite Konvertierung von Booleschen Werten zu verlassen.


Ist aus Neugier result18?
Punkrockbuddyholly

5
@MrMisterMan: Ich bin mir bei Javascript nicht sicher, aber in Java und C # ist die Auswertung garantiert von links nach rechts und das Ergebnis ist tatsächlich 18. In einigen Sprachen wie C und C ++ gibt es keine Garantie dafür Wird von links nach rechts ausgewertet, und je nach den von Ihrem Compiler hinzugefügten Optimierungen können unterschiedliche Ergebnisse erzielt werden.
Zach Johnson

9

Die Antwort auf den zweiten Teil der Frage: "Ist diese Eigenart jemals nützlich?" ist vielleicht nein, wie aus einer früheren Antwort hervorgeht, wenn es tatsächlich eine Eigenart der Sprache (Javascript) ist, dass true auf 1 gesetzt wird, der Programmierer jedoch im Allgemeinen nicht 1 und true (und 0 und false) als das betrachtet gleiche Sache.

Wenn Sie jedoch ein mentales Modell haben, bei dem 1 wahr und 0 falsch ist, führt dies zu allen möglichen netten booleschen Techniken, die äußerst nützlich, leistungsfähig und direkt sind. Sie können beispielsweise einen Zähler direkt mit dem Ergebnis von A> 100 erhöhen, wodurch der Zähler erhöht wird, wenn A größer als 100 ist. Diese Technik kann in Java als Eigenart oder Trick angesehen werden, jedoch in einem Array oder einer funktionalen Sprache kann idiomatisch sein.

Ein klassisches Beispiel in der Array-Sprache APL wäre das Zählen der Anzahl von Elementen in einem Array, die (sagen wir) größer als 100 sind:

+/A>100

Wenn A das Array mit 5 Elementen ist 107 22 256 110 3, dann:

A>100

ergibt das boolesche Array mit 5 Elementen:

1 0 1 1 0

und Summieren dieses booleschen Ergebnisses:

+/1 0 1 1 0

ergibt die endgültige Antwort:

3

Diese Frage ist ein perfektes Beispiel dafür, wo diese Technik sehr nützlich wäre, insbesondere wenn das Problem verallgemeinert wird, um festzustellen, ob n von m booleschen Werten wahr sind.

Überprüfen Sie, ob mindestens zwei von drei Booleschen Werten wahr sind


7

Das ist einfach.

(0 < 5 < 3)

Beginnen Sie mit von links nach rechts, damit die erste 0 <5 ausgewertet wird. Ist das wahr? Ja. Da TRUE = 1 ist, wird 1 <3 ausgewertet. Da 1 kleiner als 3 ist, ist es wahr.

Nun dazu

 (0 < 5 < 1)

Ist 0 kleiner als 5? Ja. Machen Sie es also WAHR, was auch 1 bedeutet. In Anbetracht dieser Tatsache ergibt es (1 <1). Ist 1 kleiner als 1? Nein, deshalb ist es falsch. Es muss gleich sein.


4

Wird 0 <5 ausgewertet, was 1 für wahr zurückgeben würde, wenn 1 <3 wahr ist?

Mit C # möchten Sie dies tun. "Operator '<' kann nicht auf Operanden vom Typ 'bool' und 'int' angewendet werden."


Manchmal vermisse ich die Strenge von C # in dynamischen Sprachen.
Arman McHitarian

4

Ich bin vor einiger Zeit in Obj-C darauf gestoßen und war sehr verwirrt darüber. Ich habe die gewünschten Ergebnisse erzielt, indem ich so etwas gemacht habe:

if(0 < 5  && 5 < 3) {
alert("True");}

Was natürlich falsch ist, damit Sie diesen "wahren" Alarm nicht erhalten. Ich bin froh, dass ich das gelesen habe, jetzt weiß ich warum.


4

Neben Python ist CoffeeScript eine weitere Sprache, die verkettete Vergleiche unterstützt und daher in Vanilla JS 3 < x < 10konvertiert wird(3 < x && x < 10)



1

Ein boolescher Operand gibt eine Zahl zurück, wenn er über einen mathematischen Operator operiert wird. um dies zu überprüfen, tun wir es

true + 1  which gives you 2.

Also 0 < 5, die zurück boolean (true) betrieben mit Mathe - Operator (<) wird eine Reihe zurück. Es kocht also auf 1 <3, was zurückkehrttrue


1

Da 0 kleiner als 5 ist, gibt dies true zurück, und standardmäßig ist true alles, einschließlich und kann zu 1 ausgewertet werden, was immer noch kleiner als 3 ist, was wiederum true zurückgibt


0

Versuchen Sie, Ihre Ergebnisse als Zahl () zu formulieren.

if(Number(0) < Number(5) < Number(3)) {
    alert("True");
}

oder versuchen Sie dies:

if(Number(0) < Number(5) && Number(5) < Number(3)) {
    alert("True");
}

Ich habe dies gegoogelt, weil ich es bekommen habe (3 >= 20) //returning trueund ich denke, Javascript hat versucht, es 3als Booleschen Wert zu überprüfen, weil ich diesen Wert von der elm.getAttribute();Funktion erhalten habe, die console.log();in String-Form gedruckt wurde.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.