Perché (0 <5 <3) restituisce vero?


348

Stavo giocando in jsfiddle.net e sono curioso di sapere perché questo ritorni vero?

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

Quindi fa questo:

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

Ma questo non:

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

Questa stranezza è mai stata utile?


12
Conosci wtfjs.com ?
Harmen,

1
Ha! No, non l'avevo mai visto prima.
punkrockbuddyholly,

Ah, le gioie delle conversioni di tipo implicito.
Jörg W Mittag,

4
Mai utile? Forse per offuscamento. :-)
Icode4food,

Perché? Inoltre, tutto è utile se riesci a trovare solo le circostanze che lo richiedono. È vero, questo è meno spesso richiesto di molti altri, ma ci sono volte, pochi e lontani tra loro per quanto possano essere, dove potrebbe essere esattamente lo strumento per il lavoro.
temporaneo

Risposte:


440

L'ordine delle operazioni (0 < 5 < 3)viene interpretato in javascript come ((0 < 5) < 3)prodotto (true < 3)e true viene conteggiato come 1, causando la restituzione di true.

Questo è anche il motivo per cui (0 < 5 < 1)restituisce false, (0 < 5)restituisce true, che viene interpretato come 1risultante (1 < 1).


158
E poiché JavaScript NON è Python. :-)
rsenna,

1
Hai risposto mentre stavo modificando la mia domanda per aggiungere il if(0 < 5 < 1) == false. Ora tutto è chiaro, grazie :)
punkrockbuddyholly,

28
Esatto, Python è l'unica lingua che conosco che tratta questa sintassi ((0 < 5) && (5 < 3)), poiché probabilmente ce ne sono altre ma non le conosco.
Alan Geleynse,

18
@Alan: Mathematica è un altro esempio.
Joren,

2
IMHO JavaScript dovrebbe aumentare TypeError quando si tenta di confrontare il valore booleano con il numero, perché non ha senso.
Michał Perłakowski,

63

La mia ipotesi è perché 0 < 5è vero, e true < 3viene lanciato su 1 < 3quale è vero.


7
Non c'è casting qui. Un cast è un operatore, che il programmatore utilizza per controllare esplicitamente un tipo. Questa è la conversione implicita da un valore booleano a un numero intero.
Erickson,

4
@erickson, davvero ... ABBIAMO BISOGNO di essere bloccati sulla semantica qui?
CaffGeek,

2
Non preoccuparti per Erickson. Uso male anche la parola semantica. :)
Mateen Ulhaq,

9
In ogni caso il termine corretto è coercizione . E sì, Erickson ha in parte torto nella sua assoluta certezza. Una coercizione è comunque una specie di cast anche se di solito (ma è solo una convenzione) usi la parola "cast" per esprimere conversioni di tipo esplicite. Tipo di conversione == Tipo casting.
Jack,

1
Sofisti fino in fondo ... La risposta è 'laconicamente' bella comunque;)
Arman McHitarian

21

probabilmente perché trueè assunto come 1tale

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


10

Quanto alla tua domanda se questa stranezza sia mai utile: suppongo che potrebbe esserci qualche caso in cui sarebbe utile (se il codice condensato è ciò che stai cercando), ma fare affidamento su di esso ridurrà (molto probabilmente) gravemente la comprensibilità del tuo codice.

È un po 'come usare post / pre incremento / decremento come parte di espressioni più grandi. Puoi determinare quali sono i risultati di questo codice a colpo d'occhio?

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

Nota: con questo codice, a volte è anche possibile ottenere risultati diversi a seconda della lingua e del compilatore.

È una buona idea semplificare la vita a te stesso e al prossimo che leggerà il tuo codice. Scrivi chiaramente quello che vuoi realmente accadere piuttosto che fare affidamento su effetti collaterali come la conversione implicita dei booleani.


Per curiosità, ha result18 anni?
punkrockbuddyholly,

5
@MrMisterMan: Non sono sicuro di Javascript, ma in Java e C # la valutazione è garantita da sinistra a destra e il risultato è effettivamente 18. In alcuni linguaggi come C e C ++, non vi è alcuna garanzia che sarà valutato da sinistra a destra e potresti ottenere risultati diversi a seconda delle ottimizzazioni aggiunte dal tuo compilatore.
Zach Johnson,

9

La risposta alla seconda parte della domanda, "questa stranezza è mai utile?" è forse no, come notato da una risposta precedente, se è davvero una stranezza del linguaggio (Javascript) che true è cast su 1, ma che il programmatore non vede in generale 1 e true (e 0 e false) come stessa cosa.

Se tuttavia hai un modello mentale di 1 che è vero e 0 che è falso, allora porta a tutti i tipi di belle tecniche booleane che sono estremamente utili, potenti e dirette. Ad esempio, è possibile incrementare un contatore direttamente con il risultato di A> 100, che aumenterebbe il contatore se A è maggiore di 100. Questa tecnica potrebbe essere vista come una stranezza o un trucco in Java, ma in un array o in un linguaggio funzionale può essere idiomatico.

Un classico esempio nel linguaggio APL dell'array sarebbe quello di contare il numero di elementi in un array che sono (diciamo) maggiori di 100:

+/A>100

Dove se A è l'array a 5 elementi 107 22 256 110 3, allora:

A>100

restituisce l'array booleano a 5 elementi:

1 0 1 1 0

e sommando questo risultato booleano:

+/1 0 1 1 0

fornisce la risposta finale:

3

Questa domanda è un esempio perfetto di dove questa tecnica sarebbe molto utile, specialmente se il problema è generalizzato per determinare se n valori booleani n su m sono veri.

Controlla se almeno due booleani su tre sono veri


7

Questo è facile.

(0 < 5 < 3)

Inizia da sinistra a destra in modo che valuti il ​​primo 0 <5. È vero? Sì. Poiché TRUE = 1, valuta 1 <3. Poiché 1 è inferiore a 3, quindi è vero.

Adesso con questo

 (0 < 5 < 1)

0 è minore di 5? Sì. Quindi rendilo VERO, che significa anche 1. Ora, tenendo presente questo fatto, valuta (1 <1). 1 è inferiore a 1? No, quindi è falso. Deve essere uguale.


4

sta valutando 0 <5 che restituirà 1 per vero quando 1 <3 che è vero?

C # vuole lasciarti fare questo "Operatore '<' non può essere applicato agli operandi di tipo 'bool' e 'int'"


A volte mi manca la severità di C # nei linguaggi dinamici.
Arman McHitarian,

4

L'ho incontrato poco fa in Obj-C e ne sono rimasto molto perplesso. Ho ottenuto i risultati desiderati facendo qualcosa del genere:

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

Che ovviamente è falso in modo da non ricevere questo "vero" avviso. Sono contento di averlo letto, ora so perché.


4

Oltre a Python, CoffeeScript è un altro linguaggio che supporta confronti concatenati, quindi 3 < x < 10verrebbe convertito (3 < x && x < 10)in JS vaniglia



1

Un operando booleano quando viene operato su un operatore matematico restituisce un numero. per controllare questo lo facciamo

true + 1  which gives you 2.

Pertanto 0 < 5, il valore booleano restituito (true) gestito con l'operatore di matematica (<) restituirà un numero. Quindi bolle a 1 <3 che ritornatrue


1

perché 0 è inferiore a 5, quindi restituisce true e, per impostazione predefinita, true è tutto compreso e può essere valutato su 1 che è comunque inferiore a 3 e restituisce true


0

prova a definire i risultati come Numero ()

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

o prova questo:

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

Ho (3 >= 20) //returning truecercato su google questo perché stavo ottenendo e immagino che javascript stesse cercando di controllare 3come un valore booleano perché stavo ottenendo questo valore dalla elm.getAttribute();funzione che console.log();stava stampando in formato String.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.