Jak parseInt()
i Number()
zachowują się inaczej przy konwersji ciągów na liczby?
Jak parseInt()
i Number()
zachowują się inaczej przy konwersji ciągów na liczby?
Odpowiedzi:
Dobrze, że są semantycznie różni The Number
konstruktor nazywa się funkcją wykonuje rodzaj konwersji i parseInt
wykonuje parsowania , na przykład:
// parsing:
parseInt("20px"); // 20
parseInt("10100", 2); // 20
parseInt("2e1"); // 2
// type conversion
Number("20px"); // NaN
Number("2e1"); // 20, exponential notation
Należy pamiętać, że jeśli parseInt
wykryje wiodące zero w ciągu, parsuje liczbę w bazie ósemkowej, zmieniło się to w ECMAScript 5, nowej wersji standardu, ale zajmie to dużo czasu, aby wejść w implementacje przeglądarki (jest to niezgodność z ECMAScript 3), również parseInt
zignoruje końcowe znaki, które nie odpowiadają żadnej cyfrze aktualnie używanej bazy.
Number
Konstruktor nie wykrywa octals:
Number("010"); // 10
parseInt("010"); // 8, implicit octal
parseInt("010", 10); // 10, decimal radix used
Ale może obsługiwać liczby w notacji szesnastkowej, podobnie jak parseInt
:
Number("0xF"); // 15
parseInt("0xF"); //15
Ponadto powszechnie stosowanym konstruktem do przeprowadzania konwersji typu numerycznego jest Unary +
Operator (s. 72) , co jest równoważne z użyciem Number
konstruktora jako funkcji:
+"2e1"; // 20
+"0xF"; // 15
+"010"; // 10
Number()
zajmuje się ósemkami podobnymi do heksadecymalnych i dwójkowych:Number('0o10') == 8
typeof parseInt("123") => number
typeof Number("123") => number
typeof new Number("123") => object (Number primitive wrapper object)
pierwsze dwa zapewniają lepszą wydajność, ponieważ zwraca element prymitywny zamiast obiektu.
new Number()
jest inny niż Number()
. typeof Number("123") => number
new Number("1") != new Number("1")
. NIGDY NIE UŻYWAJnew Number
. Nigdy, nigdy, nigdy. Number("1")
z drugiej strony jest całkowicie rozsądny.
let x = new Number("2"); let y = new Number("2");
a następnie sprawdzam równość z jakiegokolwiek powodu, if (x == y) { doSomething(); }
logicznie doSomething
należy ją wywołać. Ale nie będzie. Również jeśli było analizować tylko jeden numer let x = new Number("2");
wtedy x === 2
byłoby fałszywe. To jest wyraźny powód, dla którego nie powinieneś używaćnew Number
Jeśli szukasz wydajności, to prawdopodobnie najlepsze wyniki uzyskasz z przesunięciem bitowym w prawo "10">>0
. Również pomnóż ( "10" * 1
) lub nie ( ~~"10"
). Wszystkie z nich są znacznie szybsze Number
i parseInt
. Mają nawet „funkcję” zwracającą 0 dla argumentu braku liczby. Oto testy wydajności .
Number
i parseInt
wciąż wolniejsze o 99% niż reszta. Dodatkowo są dla mnie mniej atrakcyjne wizualnie :-)
parseInt
lub Number
są bardziej preferowane. Jeśli programujesz emulator N64 z milionami konwersji na sekundę, możesz rozważyć te sztuczki.
(2**31).toString() >> 0
przepełni się do -2147483648
. Możesz użyć >>>
zamiast tego, >>
aby JavaScript traktował operand jako 32-bitową liczbę całkowitą bez znaku , ale wtedy dowolne liczby większe niż 2**32 - 1
również się przepełniły.
Znalazłem dwa linki z wyników porównać spośród kilku sposobów przekształcania string
się int
.
parseInt(str,10)
parseFloat(str)
str << 0
+str
str*1
str-0
Number(str)
Jedną z różnic jest to, co oni moll konwertować z undefined
lub null
,
Number() Or Number(null) // returns 0
podczas
parseInt() Or parseInt(null) // returns NaN
parseInt()
:
NaN
zostanie zwrócony.parseInt()
funkcja napotka wartość nienumeryczną, odetnie resztę ciągu wejściowego i parsuje tylko część, aż do wartości nienumerycznej.undefined
0, JS przyjmie następujące założenia:
ES5
określa, że należy użyć 10. Nie jest to jednak obsługiwane przez wszystkie przeglądarki, dlatego zawsze określaj podstawę, jeśli liczby mogą zaczynać się od 0.Number()
:
Number()
Konstruktor można zamienić dowolny wejście na szereg argumentów. Jeśli Number()
konstruktor nie może przekonwertować danych wejściowych na liczbę,NaN
zostaną zwrócone.Number()
Konstruktor może również obsługiwać liczbę szesnastkową, muszą zacząć 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
Zawsze używam parseInt, ale uważaj na wiodące zera, które zmuszą go do przejścia w tryb ósemkowy .
parseInt(value, radix)
ten sposób, aby nie było przypadkowych konwersji w trybie ósemkowym itp.
0
, nawet w trybie non-ścisłym. Ale zostało to naprawione, a teraz wiodące zera są po prostu ignorowane, więc tak parseInt("070")
się stanie 70
.
parseInt()
.
parseInt()
-> Analizuje liczbę na określony redix.
Number()
-> Konwertuje podaną wartość na jej numeryczny odpowiednik lub NaN, jeśli tego nie zrobi.
Dlatego do konwersji niektórych wartości nienumerycznych na liczby zawsze należy używać funkcji Number ().
na przykład.
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
Istnieją różne przypadki narożne parseInt()
funkcji, ponieważ wykonuje konwersję remixu, dlatego powinniśmy unikać używania funkcji parseInt () do celów kooperacji.
Teraz, aby sprawdzić pogodę, podana wartość jest liczbą lub nie, powinniśmy użyć isNaN()
funkcji natywnej
parseInt konwertuje na liczbę całkowitą, co oznacza, że usuwa liczby dziesiętne. Liczba nie jest konwertowana na liczbę całkowitą.
Warto trzymać się z dala od parsowania i używać Number i Math.round, chyba że potrzebujesz hex lub ósemki. Oba mogą używać ciągów. Po co trzymać się z daleka?
parseInt(0.001, 10)
0
parseInt(-0.0000000001, 10)
-1
parseInt(0.0000000001, 10)
1
parseInt(4000000000000000000000, 10)
4
Całkowicie rzeźniczy naprawdę duże lub naprawdę małe liczby. Dziwne, że działa normalnie, jeśli te dane wejściowe są ciągiem.
parseInt("-0.0000000001", 10)
0
parseInt("0.0000000001", 10)
0
parseInt("4000000000000000000000", 10)
4e+21
Zamiast ryzykować, że nie uda mi się znaleźć błędów w tym i innych wymienionych problemach, po prostu uniknę parsowania, chyba że trzeba będzie parsować coś innego niż baza 10. Liczba, Math.round, Math.foor i .toFixed (0) mogą wszystko zrób te same rzeczy, z których można korzystać bez analizy tego typu błędów.
Jeśli naprawdę chcesz lub potrzebujesz użyć parsowania dla niektórych jego innych właściwości, nigdy nie używaj go do konwersji liczb zmiennoprzecinkowych na ints.