Jaka jest różnica między parseInt () a Number ()?


Odpowiedzi:


457

Dobrze, że są semantycznie różni The Numberkonstruktor nazywa się funkcją wykonuje rodzaj konwersji i parseIntwykonuje 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 parseIntwykryje 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ż parseIntzignoruje końcowe znaki, które nie odpowiadają żadnej cyfrze aktualnie używanej bazy.

NumberKonstruktor 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 Numberkonstruktora jako funkcji:

+"2e1";   // 20
+"0xF";   // 15
+"010";   // 10

Ciekawe, czy parsowanie nie ignoruje żadnych znaków na końcu liczby? Ponieważ w moim przypadku wolałbym otrzymać NaN zamiast 20 podczas konwersji.
Mark

Tak. Wygląda na to, że zdecydowanie chcesz Number ()
Gareth

Okej, więc chyba pójdę z Number (), ale wielkie dzięki za wyjaśnienie tego punktu i wszystkich tych przykładów! :-)
Mark

1
Dziękuję Ci za to. Po raz pierwszy widziałem NaN. Może być pomocne dla niektórych osób, aby wiedzieć, że NaN jest testowany z funkcją isNaN (wartość). Na przykład użycie „if (wartość == NaN)” nie zadziała.
WonderfulDay

1
Number()zajmuje się ósemkami podobnymi do heksadecymalnych i dwójkowych:Number('0o10') == 8
Juan Mendes

22
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.


20
new Number()jest inny niż Number(). typeof Number("123") => number
Gareth,

8
Również new Number("1") != new Number("1"). NIGDY NIE UŻYWAJnew Number . Nigdy, nigdy, nigdy. Number("1")z drugiej strony jest całkowicie rozsądny.
Kragen Javier Sitaker

18
@Kragen, byłoby znacznie korzystniejsze dla społeczności, gdybyś wyjaśnił DLACZEGO nie powinieneś używać „nowego numeru” - zamiast po prostu wpisywać „nigdy” 5 razy ...
ken

1
@ken Bardzo stary komentarz, ale dla przyszłych gości wyobrażam sobie, że to właśnie dlatego, że wymienili powód, dla którego zaczęli. Analizuję dwie liczby, let x = new Number("2"); let y = new Number("2");a następnie sprawdzam równość z jakiegokolwiek powodu, if (x == y) { doSomething(); }logicznie doSomethingnależ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 === 2byłoby fałszywe. To jest wyraźny powód, dla którego nie powinieneś używaćnew Number
Tom C

1
@TomC Widzisz wynik edytowanego komentarza (oznacza to ikonę ołówka po komentarzu); wcześniej było zero wyjaśnień, tylko silne upomnienie.
Ken

15

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 Numberi parseInt. Mają nawet „funkcję” zwracającą 0 dla argumentu braku liczby. Oto testy wydajności .


1
Szybkość różnych podejść wydaje się zmieniać wraz z wersjami przeglądarki w miarę upływu czasu. Test połączony również się zmienił, a najnowsza wersja tego komentarza jest tutaj - jsperf.com/number-vs-parseint-vs-plus/39 - na szczęście strona zawiera również poprzednie wersje testu
bobo

@ Bobo, jasne. Z ciekawości sprawdzone chromem - Numberi parseIntwciąż wolniejsze o 99% niż reszta. Dodatkowo są dla mnie mniej atrakcyjne wizualnie :-)
Saulius

15
Zawsze preferuj przejrzystość kodu zamiast „bezużytecznych” optymalizacji. W większości przypadków użycia parseIntlub Numbersą bardziej preferowane. Jeśli programujesz emulator N64 z milionami konwersji na sekundę, możesz rozważyć te sztuczki.
ngryman

1
Pytanie dotyczy zachowania, dyskusja na temat wydajności jest nie na temat.
pneumatyka

1
Pamiętaj, że nie można tego użyć w przypadku dużych liczb całkowitych - w szczególności liczb całkowitych, które nie pasują do 32-bitowej liczby całkowitej ze znakiem - ponieważ w JavaScript operatory bitowe traktują swoje operandy jako ciąg 32 bitów, a nie jako dziesiętne, liczby szesnastkowe lub ósemkowe. Dlatego (2**31).toString() >> 0przepeł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 - 1również się przepełniły.
hasc


6

Jedną z różnic jest to, co oni moll konwertować z undefinedlub null,

Number() Or Number(null) // returns 0

podczas

parseInt() Or parseInt(null) // returns NaN

6

Podsumowanie:

parseInt():

  • Bierze ciąg jako pierwszy argument, podstawa (liczba całkowita, która jest podstawą systemu liczbowego, np. Dziesiętna 10 lub binarna 2) jako drugi argument
  • Funkcja zwraca liczbę całkowitą, jeśli pierwszy znak nie może zostać przekonwertowany na liczbę, NaNzostanie zwrócony.
  • Jeśli… parseInt() funkcja napotka wartość nienumeryczną, odetnie resztę ciągu wejściowego i parsuje tylko część, aż do wartości nienumerycznej.
  • Jeśli podstawa wynosi undefined0, JS przyjmie następujące założenia:
    • Jeśli łańcuch wejściowy zaczyna się od „0x” lub „0X”, podstawa wynosi 16 (szesnastkowo), reszta łańcucha jest analizowana na liczbę.
    • Jeśli wartość wejściowa zaczyna się od 0, podstawa może być 8 (ósemkowa) lub 10 (dziesiętna). Wybór podstawy zależy od implementacji silnika JS. ES5okreś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.
    • Jeśli wartość wejściowa zaczyna się od dowolnej liczby, podstawa będzie wynosić 10

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.

Przykład:

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


5

Zawsze używam parseInt, ale uważaj na wiodące zera, które zmuszą go do przejścia w tryb ósemkowy .


35
Myślę, że zawsze dobrym pomysłem jest podanie podstawnika w parseInt(value, radix)ten sposób, aby nie było przypadkowych konwersji w trybie ósemkowym itp.
awesomo

Zer będzie zmusić go do trybu ósemkowej w ECMAScript 3. ECMAScript 5 przetworzy go 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.
Piotrek Hryciuk

2
Powinieneś także używać linijek, które ostrzegą cię o podaniu wartości radix parseInt().
Justin

2

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


1

parseInt konwertuje na liczbę całkowitą, co oznacza, że ​​usuwa liczby dziesiętne. Liczba nie jest konwertowana na liczbę całkowitą.


1

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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.