2015-12-15 15 views
8

Ho passato con domande simili e risposte su StackOverflow e abbiamo trovato questo:Perché Number ('') restituisce 0, mentre parseInt ('') restituisce NaN

parseInt("123hui") 
returns 123 

Number("123hui") 
returns NaN 

Come, parseInt() analizza fino al primo non -Digita e restituisce qualsiasi cosa abbia analizzato e Number() tenta di convertire l'intera stringa in un numero, perché il comportamento improbabile in caso di parseInt('') e Number('').

mi sento idealmente parseInt dovrebbe restituire NaN proprio come fa con Number("123hui")

Ora la mia domanda successiva:

Come 0 == '' rendimenti true Credo che interpreta come 0 == Number('') che è vero. Quindi il compilatore lo considera davvero come 0 == Number('') e non come 0 == parseInt('') o mi mancano alcuni punti?

+6

Bene, è proprio come è stato progettato per funzionare. O forse si è evoluto per lavorare in questo modo. In ogni caso, troppo tardi per cambiarlo. E ci sono buoni casi d'uso per entrambi i metodi. Hai solo bisogno di scegliere quello che è appropriato. – Thilo

+0

Si noti inoltre che 'Numero' supporta anche numeri in virgola mobile, non solo numeri interi. – Thilo

+0

Idealmente o no, non è così che funziona. Potresti apprezzare https://www.youtube.com/watch?v=FqhZZNUyVFM anche se – pvg

risposta

4

La differenza è dovuta in parte a Number() facendo uso di logica aggiuntiva per la coercizione di tipo. Escluso dalla the rules it follows per cioè:

  • Un StringNumericLiteral che è vuoto o contiene solo spazi vuoti viene convertito in +0.

considerando parseInt() è definito semplicemente trovare e valutare caratteri numerici in ingresso, in base al dato o rilevato radix. E, è stato definito per aspettarsi almeno un carattere valido.

13) Se S contiene un'unità di codice che non è un radix- R cifre, lasciate Z essere la stringa di S costituito da tutte le unità di codice prima della prima unità tale codice; in caso contrario, lasciare ZS.

14) Se Z è vuoto, restituire NaN.

Nota: 'S' è la stringa di input dopo un qualsiasi spazio viene rimosso.


Come 0=='' rendimenti true Credo che interpreta come 0==Number('') [...]

Le regole che == impieghi sono definiti come Abstract Equality.

E, hai ragione circa la coercizione/conversione che viene utilizzata.Il passo rilevante è # 6:

Se Tipo (x) è numero e il tipo (y) è String,
ritorno il risultato del confronto x == ToNumber (y).

+0

Per il tuo tipico confronto di uguaglianza (quando non provi a convertire i tipi allo stesso tempo), di solito è meglio fare '===' invece di '==' ed evitare la confusione di coercizione di tipo. – Thilo

+0

@Thilo: Beh, quando non si convertono i tipi perché entrambi sono uguali (come dovrebbero essere), non c'è confusione e si può usare anche '=='. – Bergi

-1

parseInt("") è NaN perché lo standard dice così, anche se è +""0 invece (anche semplicemente perché la norma dice così, il che implica per esempio che "" == 0).

Non cercare la logica in questo perché non c'è una logica profonda profonda, solo la cronologia .

Sei a mio parere facendo un GRANDE errore ... prima lo correggi meglio sarà per la tua programmazione con Javascript. L'errore è che si presume che ogni scelta fatta nei linguaggi di programmazione e ogni dettaglio tecnico su di essi sia logica. Questo semplicemente non è vero.

Soprattutto per Javascript.

Si prega di ricordare che Javascript è stato "progettato" in fretta e, solo a causa del destino, è diventato estremamente popolare durante la notte. Ciò ha costretto la comunità a standardizzarlo prima di qualsiasi seria riflessione sui dettagli e quindi è stato sostanzialmente "congelato" nel suo attuale stato triste prima di qualsiasi serio test sul campo.

Ci sono parti che sono così male che non sono nemmeno divertente (ad es with dichiarazione o l'operatore di uguaglianza == che è così rotto che gravi js IDE mettono in guardia contro qualsiasi uso di esso: si ottiene cose come A==B, B==C e A!=C anche utilizzando solo valori normali e senza alcun valore "speciale" come null, undefined, NaN o stringhe vuote "" e non a causa di problemi di precisione).

I casi speciali non necessari sono ovunque in Javascript e provare a metterli in una cornice logica è, sfortunatamente, uno sforzo inutile. Imparate le sue stranezze leggendo molto e godetevi il fantastico ambiente di runtime che fornisce (è qui che JavaScript brilla davvero ... i browser e le loro JIT sono una tecnologia davvero impressionante: potete scrivere poche righe e ottenere un software veramente utile in esecuzione su un gajillion di diversi dispositivi informatici).

Lo standard ufficiale in cui sono enumerate tutte le stranezze è piuttosto difficile da leggere perché mira ad essere molto preciso e purtroppo le regole che deve specificare sono davvero complesse.

Inoltre, come i guadagni linguaggio più caratteristiche le regole otterrà ancora di più e più complessa: per esempio ciò che è per ES5 solo un altro caso strano "speciale" (ad esempio ToPrimitive comportamento operazione per Date oggetti) diventa un caso "normale" in ES6 (dove ToPrimitive può essere personalizzato).

Non sono sicuro che questa "normalizzazione" sia qualcosa di cui essere contento ... il vero problema è il punto di partenza congelato e non ci sono soluzioni facili ora (se non si vuole buttare via tutto il codice javascript esistente, questo è).

Il percorso normale per una lingua inizia pulito, semplice, simmetrico e piccolo. Quindi quando si affrontano problemi del mondo reale, il linguaggio guadagna (è infetto da) alcune parti brutte (perché il mondo è brutto e asimmetrico).

Javascript è così. Tranne che non è iniziato bello e pulito e inoltre non c'è stato tempo per lucidarlo prima di lanciarlo nel gioco.

+1

L'esempio con '==' è terribile: '==' non è transitivo in molti linguaggi (anche in compilazione). – zerkms

+3

Questa è una risposta molto supponente e soggettiva, è davvero solo un lungo commento. Penso che tu abbia perso l'intero punto di javascript come un linguaggio di scripting semplice, facile da usare in cui funzionalità come l'operatore '==' hanno senso (ad es. ''1' == 1'). – RobG

+1

@RobG: '==' le regole non rendono il Javascript facile da usare, in realtà è il contrario. Finisci con programmi che a volte funzionano e a volte non per un motivo apparentemente senza motivo. A proposito, anche '1' è uguale a' [1] 'ea' "1" '(vuoto alla fine).Ma '[1]' non è uguale a '" 1 "'. Le regole non sono affatto semplici, ma piuttosto complicate e strane (controlla lo standard formale ecmascript per un po 'di divertimento) ... sono solo la formalizzazione dell'hack iniziale. Impressionante per essere un hack, ma ancora solo un hack non ben ragionato. – 6502

0

per rispondere alla tua domanda circa 0=='' restituendo vero:

Di seguito si riporta il confronto di un numero e stringa:

Il Equals Operator (==)

Type (x) Type(y)    Result 
------------------------------------------- 
x and y are the same type  Strict Equality (===) Algorithm 
Number String     x == toNumber(y) 

e toNumber esegue quanto segue per un argomento stringa:

toNumber: 

Argument type Result 
------------------------ 
String   In effect evaluates Number(string) 
       “abc” -> NaN 
       “123” -> 123 

Number('') restituisce 0. In modo che si lascia con 0==0 che viene valutata utilizzando uguaglianza rigorosa (===) Algoritmo

stretto Equals Operator (===)

Type   values      Result 
---------------------------------------------------------- 
Number  x same value as y    true 
      (but not NaN) 

È possibile trovare l'elenco completo @javascriptweblog.wordpress.com - truth-equality-and-javascript.

Problemi correlati