2012-01-22 13 views
52

Ho bisogno di confrontare due valori numerici per l'uguaglianza in Javascript. I valori possono essere anche NaN. Mi è venuta in mente questo codice:Confronto dei valori NaN per l'uguaglianza in Javascript

if (val1 == val2 || isNaN(val1) && isNaN(val2)) ... 

che sta lavorando bene, ma sembra gonfio a me. Mi piacerebbe renderlo più conciso. Qualche idea?

+7

miscelazione '||' e '' && senza qualche parentesi è estremamente brutta e confusa. – ThiefMaster

+9

'NaN' e' NaN' dovrebbero essere non uguali per un motivo, perché, ad esempio, '0/0' e' parseInt ("non un numero!") ', Mentre entrambi valutano come' NaN', dovrebbero non essere considerato uguale –

+1

@Peter a volte questa differenza è irrilevante per l'algoritmo. Penso che questo sia il caso dell'OP. – drigoangelo

risposta

44
if(val1 == val2 || (isNaN(val1) && isNaN(val2))) 

Niente da migliorare. Basta aggiungere le parentesi per renderlo chiaro a tutti.

+6

Lo migliorerei con un commento che spiega perché 'NaN === NaN' restituisce true. – Esailija

4

if (val1 === val2)

Se uno o entrambi sono NaN si valuterà su false.

Inoltre, NaN !== NaN

+0

Non è quello non equivalente?L'OP voleva che l'espressione restituisse true se sia val1 che val2 fossero '' 'NaN'''. –

5

Nan è mai uguale a se stessa, non importa il metodo di confronto, quindi l'unica soluzione più concisa per il vostro problema che mi viene in mente sarebbe quello di creare una chiamata di funzione con un nome descrittivo per fare questo confronto piuttosto speciale e utilizzare invece quella funzione di confronto nel codice.

Questo avrebbe anche il vantaggio di localizzare le modifiche all'algoritmo il giorno in cui decidi che undefined deve essere uguale a non definito.

4

Finché si sa queste due variabili sono numeriche, si può provare:

if (val1 + '' == val2 + '') 

Si scopre i due valori in stringhe. Una risposta divertente, ma dovrebbe funzionare. :)

+1

Non darà sempre un risultato identico al codice originale, ma di nuovo, nei casi in cui varrebbe, potrebbe essere un comportamento preferito. Ad esempio '" "== 0;', che è 'true', ma sarà' false' con il tuo codice. Questo può essere considerato un miglioramento. –

22

Evitare isNaN. Il suo comportamento è fuorviante:

isNaN(undefined) // true 

_.isNaN (da Underscore.js) è un elegante funzione che si comporta come previsto:

// Is the given value `NaN`? 
// 
// `NaN` is the only value for which `===` is not reflexive. 
_.isNaN = function(obj) { 
    return obj !== obj; 
}; 

_.isNaN(undefined) // false 
_.isNaN(0/0) // true 
+1

'indefinito' diventa' NaN' quando viene convertito in un 'Numero' ... comunque è molto meglio sapere che durante la fase' isNaN' di dopo. – Esailija

+7

Cosa c'è di sbagliato in 'isNaN (indefinito)' essendo 'true'? 'undefined' ** non è un numero **. Cosa sembra essere così fuorviante per te? – trejder

+5

@trejder: NaN e undefined sono valori diversi. Diversi valori * tipi *, pari. – davidchambers

1

ho creato questa risposta dopo aver esaminato i consigli di ThiefMaster, Esailija, Joachim Isaksson e davidchambers . Questo può essere ulteriormente migliorato?

// Determines if two numeric values are equal. 
// Also returns true when both parameters are NaN. 
function areEqualNumeric(val1, val2) { 
    return val1 === val2 || (val1 !== val1 && val2 !== val2); 
} 
+1

Suppongo che non sia necessario alcun ulteriore miglioramento, AngularJS utilizza esattamente lo stesso codice 'compare = function (a, b) {return a === b || (a! == a && b! == b); }; ' – Ande

2

Perché non un'istruzione if come questo?

if (isNaN(x) == true){ 
     alert("This is not a number."); 
    } 
2

Per i casi numerici la soluzione va bene ma estenderlo a lavorare per gli altri tipi di dati come pure il mio suggerimento sarebbe la seguente:

if(val1 === val2 || (val1 !== val1 && val2 !== val2)) 

Motivo essendo globale isNaN è erronea.Vi darà risultati errati in scenari come

isNaN(undefined); // true 
isNaN({});  // true 
isNaN("lorem ipsum"); // true 

Ho inviato una risposta completa qui che copre il confronto NaN per l'uguaglianza pure.

How to test if a JavaScript variable is NaN

0

confronto di uguaglianza con NaN risultati sempre in False.

Possiamo andare per la funzione javascript isNaN() per controllare l'uguaglianza con NaN. Esempio:

1. isNaN(123) //false 

2. var array = [3, NaN]; 

for(var i = 0 ; i< array.length; i++){ 
    if(isNaN(array[i])){ 
     console.log("True ---- Values of " + i); 
    } else { 
     console.log("false ---- Values of " + i); 
    } 
} 

Risultati:

falsi ---- valori di 0

Veri ---- valori di 1

-1

trovato un altro modo mediante Array. prototype.includes MDN link. Apparentemente, [NaN] .include (NaN) restituisce true per NaN.

function IsActuallyNaN(obj) { 
    return [obj].includes(NaN); 
} 

Oppure possiamo andare con la soluzione di davidchambers che è molto più semplice.

function IsActuallyNaN2(obj) { 
    return obj !== obj; 
} 
+0

quando scrivi una risposta su SO cerca sempre di dare poche spiegazioni sul tuo codice. –

+0

Non costruire un array letterale solo per questo. Se vuoi usare i metodi ES6, usa 'Object.is (obj, NaN)' – Bergi

1

Prova utilizzando Object.is(), determina se due valori sono lo stesso valore. Due valori sono uguali se una delle seguenti vale:

sia indefinito

sia nullo

sia vero o entrambe false

entrambe le stringhe della stessa lunghezza con gli stessi caratteri nello stesso ordine

sia lo stesso oggetto

entrambi i numeri e

sia +0

sia -0

sia NaN

esempio Object.is (Nan) => true

Suggerire https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is

Problemi correlati