Come si comportano parseInt()
e si Number()
comportano diversamente quando si convertono le stringhe in numeri?
Come si comportano parseInt()
e si Number()
comportano diversamente quando si convertono le stringhe in numeri?
Risposte:
Bene, sono semanticamente diversi , il Number
costruttore chiamato come funzione esegue la conversione del tipo ed parseInt
esegue l' analisi , ad esempio:
// parsing:
parseInt("20px"); // 20
parseInt("10100", 2); // 20
parseInt("2e1"); // 2
// type conversion
Number("20px"); // NaN
Number("2e1"); // 20, exponential notation
Tieni presente che se parseInt
rileva uno zero iniziale sulla stringa, analizzerà il numero in base ottale, questo è cambiato su ECMAScript 5, la nuova versione dello standard, ma ci vorrà molto tempo per ottenere le implementazioni del browser (è incompatibilità con ECMAScript 3), parseInt
ignorerà anche i caratteri finali che non corrispondono a nessuna cifra della base attualmente utilizzata.
Il Number
costruttore non rileva ottali:
Number("010"); // 10
parseInt("010"); // 8, implicit octal
parseInt("010", 10); // 10, decimal radix used
Ma può gestire i numeri in notazione esadecimale, proprio come parseInt
:
Number("0xF"); // 15
parseInt("0xF"); //15
Inoltre, un costrutto ampiamente utilizzato per eseguire la conversione di tipo numerico, è l' operatore unario +
(p. 72) , equivale a utilizzare il Number
costruttore come funzione:
+"2e1"; // 20
+"0xF"; // 15
+"010"; // 10
Number()
tratta ottali in modo molto simile a esadecimale e binario:Number('0o10') == 8
typeof parseInt("123") => number
typeof Number("123") => number
typeof new Number("123") => object (Number primitive wrapper object)
i primi due ti daranno prestazioni migliori in quanto restituisce una primitiva anziché un oggetto.
new Number()
è diverso da Number()
. typeof Number("123") => number
new Number("1") != new Number("1")
. MAI USAREnew Number
. Mai e poi mai e poi mai. Number("1")
d'altra parte, è perfettamente ragionevole.
let x = new Number("2"); let y = new Number("2");
e successivamente eseguo un controllo di uguaglianza per qualsiasi motivo, if (x == y) { doSomething(); }
logicamente doSomething
dovrebbe essere chiamato. Ma non lo farà. Anche se si dovesse analizzare solo un numero let x = new Number("2");
, allora x === 2
sarebbe falsa. Questo è un chiaro motivo per cui non dovresti usarenew Number
Se stai cercando prestazioni, probabilmente i migliori risultati otterrai con il giusto spostamento bit a bit "10">>0
. Moltiplica anche ( "10" * 1
) o no ( ~~"10"
). Tutti sono molto più veloci di Number
e parseInt
. Hanno anche "feature" che restituisce 0 per argomento non numerico. Ecco i test delle prestazioni .
Number
e parseInt
ancora più lenta del 99% rispetto al resto. Inoltre per me sono anche meno attraenti visivamente :-)
parseInt
o Number
sono più preferibili. Se stai programmando un emulatore N64 con milioni di conversioni al secondo, potresti prendere in considerazione questi trucchi.
(2**31).toString() >> 0
traboccerà -2147483648
. È possibile utilizzare >>>
invece di >>
fare in modo che JavaScript consideri l'operando come un numero intero a 32 bit senza segno , ma anche tutti i numeri più grandi di quelli 2**32 - 1
supereranno.
Ho trovato due link di prestazioni confronto tra i diversi modi di conversione string
a int
.
parseInt(str,10)
parseFloat(str)
str << 0
+str
str*1
str-0
Number(str)
Una differenza minore è ciò di cui convertono undefined
o null
,
Number() Or Number(null) // returns 0
mentre
parseInt() Or parseInt(null) // returns NaN
parseInt()
:
NaN
verrà restituito.parseInt()
funzione incontra un valore non numerico, interromperà il resto della stringa di input e analizzerà la parte solo fino al valore non numerico.undefined
o 0, JS assumerà quanto segue:
ES5
specifica che 10 dovrebbe essere usato allora. Tuttavia, questo non è supportato da tutti i browser, quindi specifica sempre radix se i tuoi numeri possono iniziare con uno 0.Number()
:
Number()
costruttore può convertire qualsiasi input di argomento in un numero. Se il Number()
costruttore non può convertire l'input in un numero, NaN
verrà restituito.Number()
costruttore può anche gestire un numero esadecimale, che deve iniziare 0x
.console.log(parseInt('0xF', 16)); // 15
// z is no number, it will only evaluate 0xF, therefore 15 is logged
console.log(parseInt('0xFz123', 16));
// because the radix is 10, A is considered a letter not a number (like in Hexadecimal)
// Therefore, A will be cut off the string and 10 is logged
console.log(parseInt('10A', 10)); // 10
// first character isnot a number, therefore parseInt will return NaN
console.log(parseInt('a1213', 10));
console.log('\n');
// start with 0X, therefore Number will interpret it as a hexadecimal value
console.log(Number('0x11'));
// Cannot be converted to a number, NaN will be returned, notice that
// the number constructor will not cut off a non number part like parseInt does
console.log(Number('123A'));
// scientific notation is allowed
console.log(Number('152e-1')); // 15.21
Uso sempre parseInt, ma attenzione agli zero iniziali che lo costringeranno in modalità ottale .
parseInt(value, radix)
quel modo in cui non hai conversioni accidentali in modalità ottale , ecc.
0
, anche in modalità non rigorosa. Ma questo è stato risolto e ora gli zero iniziali vengono semplicemente ignorati, così parseInt("070")
diventerebbe 70
.
parseInt()
.
parseInt()
-> Analizza un numero in redix specificato.
Number()
-> Converte il valore specificato nel suo equivalente numerico o NaN se non riesce.
Quindi per convertire un valore non numerico in numero dovremmo sempre usare la funzione Number ().
per esempio.
Number("")//0
parseInt("")//NaN
Number("123")//123
parseInt("123")//123
Number("123ac") //NaN,as it is a non numeric string
parsInt("123ac") //123,it parse decimal number outof string
Number(true)//1
parseInt(true) //NaN
Ci sono vari casi d'angolo nelle parseInt()
funzioni così come nella conversione di redix, quindi dovremmo evitare di usare la funzione parseInt () per scopi di coesione.
Ora, per controllare il tempo il valore fornito è Numerico o no, dovremmo usare la isNaN()
funzione nativa
parseInt converte in un numero intero, ovvero rimuove i decimali. Il numero non viene convertito in intero.
È una buona idea stare lontano da parseInt e usare Number e Math.round a meno che tu non abbia bisogno di hex o ottale. Entrambi possono usare le stringhe. Perché starne alla larga?
parseInt(0.001, 10)
0
parseInt(-0.0000000001, 10)
-1
parseInt(0.0000000001, 10)
1
parseInt(4000000000000000000000, 10)
4
Macella completamente numeri molto grandi o molto piccoli. Stranamente funziona normalmente se questi input sono una stringa.
parseInt("-0.0000000001", 10)
0
parseInt("0.0000000001", 10)
0
parseInt("4000000000000000000000", 10)
4e+21
Invece di rischiare duramente di trovare bug con questo e gli altri personaggi citati, eviterei semplicemente parseInt a meno che non sia necessario analizzare qualcosa di diverso dalla base 10. Numero, Math.round, Math.foor e .toFixed (0) possono tutti fare le stesse cose per cui parseInt può essere usato senza questi tipi di bug.
Se vuoi davvero o hai bisogno di usare parseInt per alcune delle sue altre qualità, non usarlo mai per convertire float in ints.