(Wbudowany) sposób w JavaScript, aby sprawdzić, czy ciąg jest poprawną liczbą

1188

Mam nadzieję, że jest coś w tej samej przestrzeni koncepcyjnej co stara IsNumeric()funkcja VB6 ?

Electrons_Ahoy
źródło
3
Zobacz to powiązane pytanie , które zadałem jakiś czas temu.
Michael Haren,
38
Jeśli przejdziesz do tego pytania, spróbuj pominąć wszystkie odpowiedzi RegEx. To po prostu NIE jest sposób, aby to zrobić.
Joel Coehoorn,
14
Chyba że ktoś chce to zrobić dokładnie: Aby sprawdzić, czy dany ciąg ma format prawidłowego strumienia cyfr. Dlaczego więc miałoby być źle?
SasQ
17
Wybrana odpowiedź jest niepoprawna !!! Zobacz swoje uwagi, ale w zasadzie to nie z np isNaN(""), isNaN(" "), isNaN(false), zwroty itp falsedla nich, co oznacza, że są one liczbami.
Andrew
1
więc wybrana odpowiedź jest niepoprawna, wyrażenie regularne nie jest na to sposobem. Który z nich jest zatem poprawny?
vir us

Odpowiedzi:

2321

Aby sprawdzić, czy zmienna (w tym ciąg) jest liczbą, sprawdź, czy nie jest liczbą:

Działa to niezależnie od tego, czy zawartość zmiennej jest łańcuchem, czy liczbą.

isNaN(num)         // returns true if the variable does NOT contain a valid number

Przykłady

isNaN(123)         // false
isNaN('123')       // false
isNaN('1e10000')   // false (This translates to Infinity, which is a number)
isNaN('foo')       // true
isNaN('10px')      // true

Oczywiście możesz to zanegować, jeśli potrzebujesz. Na przykład, aby zaimplementować podany IsNumericprzykład:

function isNumeric(num){
  return !isNaN(num)
}

Aby przekonwertować ciąg zawierający liczbę na liczbę:

Działa tylko, jeśli ciąg zawiera tylko znaki numeryczne, w przeciwnym razie zwraca NaN.

+num               // returns the numeric value of the string, or NaN 
                   // if the string isn't purely numeric characters

Przykłady

+'12'              // 12
+'12.'             // 12
+'12..'            // NaN
+'.12'             // 0.12
+'..12'            // NaN
+'foo'             // NaN
+'12px'            // NaN

Aby przekonwertować ciąg luźno na liczbę

Przydatny do konwersji „12px” na 12, na przykład:

parseInt(num)      // extracts a numeric value from the 
                   // start of the string, or NaN.

Przykłady

parseInt('12')     // 12
parseInt('aaa')    // NaN
parseInt('12px')   // 12
parseInt('foo2')   // NaN      These last two may be different
parseInt('12a5')   // 12       from what you expected to see. 

Pływaki

Należy pamiętać, że w przeciwieństwie +num, parseInt(jak sama nazwa wskazuje) będzie przekonwertować pływaka do liczby całkowitej przez odcięcie wszystkiego po przecinku (jeśli chcesz korzystać parseInt() z powodu tego zachowania, jesteś zapewne lepiej wyłączyć za pomocą innej metody zamiast ) :

+'12.345'          // 12.345
parseInt(12.345)   // 12
parseInt('12.345') // 12

Puste łańcuchy

Puste łańcuchy mogą być nieco sprzeczne z intuicją. +numkonwertuje puste ciągi lub ciągi ze spacjami na zero i isNaN()przyjmuje to samo:

+''                // 0
+'   '             // 0
isNaN('')          // false
isNaN('   ')       // false

Ale parseInt()nie zgadza się:

parseInt('')       // NaN
parseInt('   ')    // NaN
Dan
źródło
133
Bardzo ważną uwagą na temat parseInt jest to, że pozwoli ci określić podstawkę do konwersji łańcucha na int. To duża gotcha, która próbuje odgadnąć dla ciebie podstawkę, jeśli jej nie dostarczysz. Na przykład: parseInt („17”) daje 17 (dziesiętnie, 10), ale parseInt („08”) daje 0 (ósemkowe, 8). Tak więc, chyba że masz zamiar inaczej, najbezpieczniej jest użyć parseInt (liczba, 10), podając wyraźnie 10 jako podstawę.
Adam Raney
36
Zauważ, że! IsNaN (niezdefiniowany) zwraca false.
David Hellsing,
111
Jest to po prostu błędne - skąd tyle głosów poparcia? Nie można użyć opcji isNaN„Aby sprawdzić, czy zmienna nie jest liczbą”. „not a number” to nie to samo co „IEEE-794 NaN”, na co się isNaNsprawdza. W szczególności to użycie kończy się niepowodzeniem, przynajmniej podczas testowania wartości logicznych i pustych ciągów. Zobacz developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… .
EML
46
Najszybszym możliwym sposobem sprawdzenia, czy coś jest liczbą, jest sprawdzenie „równe sobie”: var n = 'a'; if (+n === +n) { // is number }Jest to ~ 3994% szybsze niż isNaN w najnowszej wersji Chrome. Zobacz test wydajności tutaj: jsperf.com/isnan-vs-typeof/5
Kevin Jurkowski
22
** Ostrzeżenie ** Ta odpowiedź jest nieprawidłowa. Używaj na własne ryzyko. Przykład:isNaN(1 + false + parseInt("1.do you trust your users?"))
keithpjolley
55

I możesz przejść w RegExp:

var num = "987238";

if(num.match(/^-{0,1}\d+$/)){
  //valid integer (positive or negative)
}else if(num.match(/^\d+\.\d+$/)){
  //valid float
}else{
  //not valid number
}
rykanie
źródło
40
W takim przypadku RegExp == zły
Joel Coehoorn
10
Nie udaje się to na liczbach szesnastkowych (na przykład 0x12), unosi się bez wiodącego zera (na przykład 0,42) i liczb ujemnych.
Ori
17
@JoelCoehoorn Chcesz wyjaśnić, dlaczego RegExp == źle tutaj? Wydaje mi się to uzasadnionym przypadkiem użycia.
computrius
6
Jest więcej sposobów niż wydaje się budować liczbę (liczby szesnastkowe w innym komentarzu są tylko jednym przykładem) i istnieje wiele liczb, które mogą nie być uważane za poprawne (przepełnienie typu, zbyt precyzyjne itp.). Ponadto wyrażenie regularne jest wolniejsze i bardziej skomplikowane niż używanie wbudowanych mechanizmów
Joel Coehoorn
1
powinien również pasować do zapisu naukowego ... 1e10 itp.
Joseph Merdrignac
51

Jeśli próbujesz tylko sprawdzić, czy ciąg jest liczbą całkowitą (bez miejsc dziesiętnych), regex jest dobrym sposobem. Inne metody isNaNsą zbyt skomplikowane dla czegoś tak prostego.

function isNumeric(value) {
    return /^-{0,1}\d+$/.test(value);
}

console.log(isNumeric('abcd'));         // false
console.log(isNumeric('123a'));         // false
console.log(isNumeric('1'));            // true
console.log(isNumeric('1234567890'));   // true
console.log(isNumeric('-23'));          // true
console.log(isNumeric(1234));           // true
console.log(isNumeric('123.4'));        // false
console.log(isNumeric(''));             // false
console.log(isNumeric(undefined));      // false
console.log(isNumeric(null));           // false

Aby zezwolić tylko na dodatnie liczby całkowite, użyj tego:

function isNumeric(value) {
    return /^\d+$/.test(value);
}

console.log(isNumeric('123'));          // true
console.log(isNumeric('-23'));          // false
Gavin
źródło
11
console.log (isNumeric ('- 1'));
yongnan
5
console.log (isNumeric ('2e2'));
Gaël Barbin
11
Być może po prostu zmień nazwę „isNumeric” na „hasOnlyDigits”. w wielu przypadkach jest to dokładnie to, czego szukasz.
gus3001
1
Właśnie tego szukałem, odpowiednika php ctype_digit
Miguel Pynto,
/^-?\d+$/dobrze?
Sukima
36

Jeśli naprawdę chcesz, aby upewnić się, że ciąg zawiera tylko numer, dowolną liczbę (całkowitej lub zmiennoprzecinkową), a dokładnie numeru, to nie można używać parseInt()/ parseFloat(), Number()albo !isNaN()przez samych siebie. Zauważ, że !isNaN()tak naprawdę zwraca, truekiedy Number()zwróci liczbę, a falsekiedy wróci NaN, więc wykluczę ją z dalszej dyskusji.

Problem parseFloat()polega na tym, że zwróci liczbę, jeśli ciąg zawiera dowolną liczbę, nawet jeśli ciąg nie zawiera tylko i dokładnie liczby:

parseFloat("2016-12-31")  // returns 2016
parseFloat("1-1") // return 1
parseFloat("1.2.3") // returns 1.2

Problem Number()polega na tym, że zwraca liczbę w przypadkach, gdy przekazana wartość wcale nie jest liczbą!

Number("") // returns 0
Number(" ") // returns 0
Number(" \u00A0   \t\n\r") // returns 0

Problem z rzutowaniem własnego wyrażenia regularnego polega na tym, że dopóki nie utworzysz dokładnego wyrażenia regularnego w celu dopasowania liczby zmiennoprzecinkowej, ponieważ JavaScript rozpozna go, przegapisz przypadki lub rozpoznasz przypadki, w których nie powinieneś. A nawet jeśli potrafisz stworzyć własne wyrażenie regularne, dlaczego? Istnieją prostsze wbudowane sposoby, aby to zrobić.

Okazuje się jednak, że Number()(i isNaN()) robi to dobrze w każdym przypadku, gdy parseFloat()zwraca liczbę, gdy nie powinna, i na odwrót. Aby dowiedzieć się, czy łańcuch jest naprawdę dokładnie i tylko liczbą, wywołaj obie funkcje i sprawdź, czy oba zwracają wartość true:

function isNumber(str) {
  if (typeof str != "string") return false // we only process strings!
  // could also coerce to string: str = ""+str
  return !isNaN(str) && !isNaN(parseFloat(str))
}
Michał
źródło
2
Zwraca wartość true, gdy ciąg ma spacje wiodące lub końcowe. ' 1', '2 'A ' 3 'wszystko return true.
Rudey,
Dodanie czegoś takiego do instrukcji return rozwiązałoby to: &&! / ^ \ S + | \ s + $ / g.test (str)
Ultroman the Tacoman
2
@RuudLenders - większość ludzi nie będzie dbać o to, czy są spłaszczane spacje, aby ciąg był prawidłową liczbą, ponieważ łatwo jest przypadkowo wstawić dodatkowe spacje na wielu interfejsach.
Ian
3
Tak jest w przypadku, gdy ciąg liczb pochodzi z danych wprowadzonych przez użytkownika. Ale pomyślałem, że i tak powinienem wspomnieć o spacjach, ponieważ myślę, że większość ludzi, którzy potrzebują isNumberfunkcji, nie ma do czynienia z interfejsami użytkownika. Również dobre wprowadzanie liczb nie pozwoli na rozpoczęcie spacji.
Rudey,
36

Przyjęta odpowiedź na to pytanie ma kilka wad (podkreślonych przez kilku innych użytkowników). Jest to jeden z najprostszych i sprawdzonych sposobów podejścia do tego w javascript:

function isNumeric(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

Poniżej kilka dobrych przypadków testowych:

console.log(isNumeric(12345678912345678912)); // true
console.log(isNumeric('2 '));                 // true
console.log(isNumeric('-32.2 '));             // true
console.log(isNumeric(-32.2));                // true
console.log(isNumeric(undefined));            // false

// the accepted answer fails at these tests:
console.log(isNumeric(''));                   // false
console.log(isNumeric(null));                 // false
console.log(isNumeric([]));                   // false
Hamzeen Hameem
źródło
22

Wypróbuj funkcję isNan :

Funkcja isNaN () określa, czy wartość jest niedozwoloną liczbą (nie-liczbą).

Ta funkcja zwraca true, jeśli wartość jest równa NaN. W przeciwnym razie zwraca false.

Ta funkcja różni się od specyficznej dla liczby metody Number.isNaN () .

  Globalna funkcja isNaN () konwertuje testowaną wartość na liczbę, a następnie ją testuje.

Number.isNan () nie konwertuje wartości na liczbę i nie zwraca wartości true dla żadnej wartości, która nie jest typu liczba ...

theraccoonbear
źródło
2
Upewnij się, że dodałeś czek na pusty ciąg. isNaN ('') zwraca false, ale prawdopodobnie w tym przypadku chcesz, aby zwrócił true.
Michael Haren,
3
isFinite jest lepszym rozwiązaniem - zajmuje się
dziwnym
3
@MichaelHaren Nie wystarczy! isNaN()powraca falsedo JAKIEGOKOLWIEK ciąg znaków zawierające tylko białe znaki, w tym takie rzeczy jak „\ u00A0”.
Michael
1
OSTRZEŻENIE: Nie działa dla wartości: null, „” (pusty ciąg) i false.
Jenny O'Reilly,
Zdaję sobie sprawę, że ta odpowiedź została udzielona 11 lat temu i kilka minut przed odpowiedzią zaakceptowaną, ale podoba mi się lub nie, zaakceptowana odpowiedź OZNACZA więcej rozmów, więc ta odpowiedź tak naprawdę nie dodaje nic do odpowiedzi na pytanie. Proponuję usunąć go, aby uniknąć rozpraszania uwagi nowych czytelników. Myślę też, że jeśli to zrobisz, dostaniesz odznakę Dyscypliny.
Dan Dascalescu
14

Stare pytanie, ale w podanych odpowiedziach brakuje kilku punktów.

Notacja naukowa.

!isNaN('1e+30')jest truejednak w większości przypadków, gdy ludzie pytają o liczby, nie chcą dopasowywać takich rzeczy 1e+30.

Duże liczby zmiennoprzecinkowe mogą zachowywać się dziwnie

Obserwuj (używając Node.js):

> var s = Array(16 + 1).join('9')
undefined
> s.length
16
> s
'9999999999999999'
> !isNaN(s)
true
> Number(s)
10000000000000000
> String(Number(s)) === s
false
>

Z drugiej strony:

> var s = Array(16 + 1).join('1')
undefined
> String(Number(s)) === s
true
> var s = Array(15 + 1).join('9')
undefined
> String(Number(s)) === s
true
>

Tak więc, jeśli się tego spodziewasz String(Number(s)) === s, lepiej ogranicz swoje łańcuchy maksymalnie do 15 cyfr (po pominięciu zer wiodących).

Nieskończoność

> typeof Infinity
'number'
> !isNaN('Infinity')
true
> isFinite('Infinity')
false
>

Biorąc to wszystko pod uwagę, sprawdzanie, czy podany ciąg jest liczbą spełniającą wszystkie poniższe kryteria:

  • notacja nienaukowa
  • przewidywalna konwersja do Numberi powrót doString
  • skończone

nie jest takie łatwe zadanie. Oto prosta wersja:

  function isNonScientificNumberString(o) {
    if (!o || typeof o !== 'string') {
      // Should not be given anything but strings.
      return false;
    }
    return o.length <= 15 && o.indexOf('e+') < 0 && o.indexOf('E+') < 0 && !isNaN(o) && isFinite(o);
  }

Jednak nawet ten jest daleki od ukończenia. Zera wiodące nie są tutaj obsługiwane, ale wkręcają test długości.

znak
źródło
1
„jednak w większości przypadków, gdy ludzie pytają o liczby, nie chcą dopasowywać takich rzeczy, jak 1e + 30”. Dlaczego miałbyś to powiedzieć? Jeśli ktoś chce wiedzieć, czy ciąg zawiera liczbę, wydaje mi się, że chciałby wiedzieć, czy zawiera on liczbę, a 1e + 30 to liczba. Oczywiście, gdybym testował ciąg znaków pod kątem wartości liczbowej w JavaScript, chciałbym, żeby to pasowało.
Dan Jones
9

Przetestowałem i rozwiązanie Michaela jest najlepsze. Głosuj na jego odpowiedź powyżej (wyszukaj na tej stronie „Jeśli naprawdę chcesz się upewnić, że ciąg znaków”, aby go znaleźć). Zasadniczo jego odpowiedź brzmi:

function isNumeric(num){
  num = "" + num; //coerce num to be a string
  return !isNaN(num) && !isNaN(parseFloat(num));
}

Działa dla każdego przypadku testowego, który tutaj udokumentowałem: https://jsfiddle.net/wggehvp9/5/

Wiele innych rozwiązań zawodzi w tych przypadkach na krawędziach: „”, null, „”, true i []. Teoretycznie można ich używać z odpowiednią obsługą błędów, na przykład:

return !isNaN(num);

lub

return (+num === +num);

ze specjalną obsługą dla / \ s /, null, "", true, false, [] (i innych?)

JohnP2
źródło
1
To nadal zwraca wartość true dla spacji końcowych / wiodących. Dodanie czegoś takiego do instrukcji return rozwiązałoby to: &&! / ^ \ S + | \ s + $ / g.test (str)
Ultroman the Tacoman
2
Zatem „123” powinno być fałszem, a nie liczbą, a „1234” powinno być liczbą? Podoba mi się, jak to jest, więc „123” jest liczbą, ale może to zależeć od uznania programisty, czy wiodące lub końcowe spacje powinny zmienić wartość.
JohnP2
8

Można użyć wynik Ilość przechodząc argument do jego konstruktora.

Jeśli argument (ciąg znaków) nie może zostać przekonwertowany na liczbę, zwraca NaN, więc można określić, czy podany ciąg był poprawną liczbą, czy nie.

Uwagi: Uwaga podczas mijania lub pusty ciąg '\t\t'i '\n\t'tak Ilość powróci 0; Przekazanie true zwróci 1, a false zwróci 0.

    Number('34.00') // 34
    Number('-34') // -34
    Number('123e5') // 12300000
    Number('123e-5') // 0.00123
    Number('999999999999') // 999999999999
    Number('9999999999999999') // 10000000000000000 (integer accuracy up to 15 digit)
    Number('0xFF') // 255
    Number('Infinity') // Infinity  

    Number('34px') // NaN
    Number('xyz') // NaN
    Number('true') // NaN
    Number('false') // NaN

    // cavets
    Number('    ') // 0
    Number('\t\t') // 0
    Number('\n\t') // 0
GibboK
źródło
NumberKonstruktor jest dokładnie taka sama jak +x.
GregRos
Na marginesie, należy pamiętać, że ES6 Number()obsługuje również liczby zmiennoprzecinkowe, jak Number.parseFloat()nieNumber.parseInt()
zurfyx
7

Być może jedna lub dwie osoby napotykają to pytanie, które wymagają znacznie bardziej rygorystycznej kontroli niż zwykle (tak jak ja). W takim przypadku może to być przydatne:

if(str === String(Number(str))) {
  // it's a "perfectly formatted" number
}

Strzec się! Będzie to odrzucić sznurki jak .1, 40.000, 080, 00.1. Jest bardzo wybredny - ciąg musi pasować do „ najbardziej minimalnej idealnej formy ” liczby, aby ten test mógł przejść pomyślnie.

Używa konstruktora Stringi Numberdo rzutowania łańcucha na liczbę iz powrotem, a tym samym sprawdza, czy „idealna minimalna forma” silnika JavaScript (ta, na którą został przekonwertowany za pomocą początkowego Numberkonstruktora) odpowiada oryginalnemu ciągowi.


źródło
2
Dzięki @JoeRocc. Musiałem to też, ale tylko dla liczb całkowitych, więc dodałem: (str === String(Math.round(Number(str)))).
keithpjolley
Należy pamiętać, że "Infinity", "-Infinity"i "NaN"zdać ten test. Można to jednak naprawić za pomocą dodatkowego Number.isFinitetestu.
GregRos
To jest dokładnie to samo co str === ("" + +str). Zasadniczo sprawdza, czy ciąg jest wynikiem strunowania numeru JS. Wiedząc o tym, możemy również zobaczyć problem: test zalicza się, 0.000001ale nie 0.0000001zalicza się, czyli wtedy, gdy 1e-7przechodzi. To samo dotyczy bardzo dużych liczb.
GregRos
5

parseInt (), ale należy pamiętać, że ta funkcja jest nieco inna w tym sensie, że zwraca na przykład 100 dla parseInt („100px”).

liggett78
źródło
I 11 za parseInt(09).
djechlin
10
ponieważ musisz użyćparaseInt(09, 10)
Gavin
1
Od ECMAScript 5 , który obsługuje szeroką przeglądarkę (IE≥9), nie potrzebujesz już , 10argumentu. parseInt('09')wynosi teraz 9.
Rory O'Kane
4

Zacytować:

isNaN (num) // zwraca true, jeśli zmienna NIE zawiera poprawnej liczby

nie jest do końca prawdą, jeśli musisz sprawdzić początkowe / końcowe spacje - na przykład, gdy wymagana jest pewna liczba cyfr, i musisz, powiedzmy, „1111”, a nie „111” lub „111”, być może kod PIN Wejście.

Lepszy w użyciu:

var num = /^\d+$/.test(num)
Siubear
źródło
Wartości '-1', '0.1'i '1e10'wszystkie fałszywe zamian. Ponadto wartości większe niż dodatnia nieskończoność lub mniejsze niż ujemna nieskończoność zwracają wartość true, podczas gdy prawdopodobnie powinny zwracać wartość false.
Rudey,
4

Dlaczego implementacja jQuery nie jest wystarczająco dobra?

function isNumeric(a) {
    var b = a && a.toString();
    return !$.isArray(a) && b - parseFloat(b) + 1 >= 0;
};

Michael zasugerował coś takiego (chociaż ukradłem tutaj „user1691651 - John” zmienioną wersję tutaj):

function isNumeric(num){
    num = "" + num; //coerce num to be a string
    return !isNaN(num) && !isNaN(parseFloat(num));
}

Poniżej przedstawiono rozwiązanie, które najprawdopodobniej ma niską wydajność, ale dobre wyniki. Jest to urządzenie wykonane z implementacji jQuery 1.12.4 i odpowiedzi Michaela, z dodatkowym sprawdzaniem początkowych / końcowych spacji (ponieważ wersja Michaela zwraca wartość true dla liczb z wiodącymi / końcowymi spacjami):

function isNumeric(a) {
    var str = a + "";
    var b = a && a.toString();
    return !$.isArray(a) && b - parseFloat(b) + 1 >= 0 &&
           !/^\s+|\s+$/g.test(str) &&
           !isNaN(str) && !isNaN(parseFloat(str));
};

Ta ostatnia wersja ma jednak dwie nowe zmienne. Można obejść jedną z nich, wykonując:

function isNumeric(a) {
    if ($.isArray(a)) return false;
    var b = a && a.toString();
    a = a + "";
    return b - parseFloat(b) + 1 >= 0 &&
            !/^\s+|\s+$/g.test(a) &&
            !isNaN(a) && !isNaN(parseFloat(a));
};

Nie testowałem żadnego z nich zbyt wiele, w inny sposób niż ręczne testowanie kilku przypadków użycia, które uderzam z moim obecnym trudem, który jest bardzo standardowy. Jest to sytuacja „stojąca na ramionach gigantów”.

Ultroman the Tacoman
źródło
4

Nie jest poprawny dla TypeScript, ponieważ:

declare function isNaN(number: number): boolean;

W przypadku TypeScript możesz użyć:

/^\d+$/.test(key)

Greg Woz
źródło
3

Używam tego, który zrobiłem ...

Dotychczas działał:

function checkNumber(value) {
    if ( value % 1 == 0 )
    return true;
    else
    return false;
}

Jeśli zauważysz jakiś problem, powiedz mi, proszę.

Rafael
źródło
12
To daje zły wynik dla pustego łańcucha, pustej tablicy, fałszu i wartości null.
Ori
2
Czy nie powinno to być potrójne równe?
toasted_flakes
1
W mojej aplikacji dopuszczamy tylko znaki AZ AZ i 0–9. Okazało się, że powyższe zadziałało, chyba że ciąg zaczyna się od 0xnn, a następnie zwróci go jako wartość liczbową, gdy nie powinien. Napisałem w komentarzu poniżej, więc formatowanie jest nienaruszone.
rwheadon
6
możesz po prostu zrobić „zwróć wartość% 1 === 0”
Brian Schermerhorn
Po prostu zróbreturn !isNaN(parseInt(value, 10));
DarkNeuron,
3

Jeśli ktokolwiek kiedykolwiek znajdzie się tak daleko, spędziłem trochę czasu włamując się do tego, próbując załatać moment.js ( https://github.com/moment/moment ). Oto coś, co mu zabrałem:

function isNumeric(val) {
    var _val = +val;
    return (val !== val + 1) //infinity check
        && (_val === +val) //Cute coercion check
        && (typeof val !== 'object') //Array/object check
}

Obsługuje następujące przypadki:

Prawdziwe! :

isNumeric("1"))
isNumeric(1e10))
isNumeric(1E10))
isNumeric(+"6e4"))
isNumeric("1.2222"))
isNumeric("-1.2222"))
isNumeric("-1.222200000000000000"))
isNumeric("1.222200000000000000"))
isNumeric(1))
isNumeric(0))
isNumeric(-0))
isNumeric(1010010293029))
isNumeric(1.100393830000))
isNumeric(Math.LN2))
isNumeric(Math.PI))
isNumeric(5e10))

Fałszywe! :

isNumeric(NaN))
isNumeric(Infinity))
isNumeric(-Infinity))
isNumeric())
isNumeric(undefined))
isNumeric('[1,2,3]'))
isNumeric({a:1,b:2}))
isNumeric(null))
isNumeric([1]))
isNumeric(new Date()))

Jak na ironię, z którą walczę najbardziej:

isNumeric(new Number(1)) => false

Wszelkie sugestie są mile widziane. :]

Dembiński
źródło
2
Co z isNumeric(' ')i isNumeric('')?
Alex Cory
Dodałbym && (val.replace(/\s/g,'') !== '') //Empty && (val.slice(-1) !== '.') //Decimal without Number, aby rozwiązać wyżej wymieniony problem i taki, który miałem sam.
frankenapps,
3

Używając zwykłego JavaScript:

Number.isNaN(Number('1')); // false
Number.isNaN(Number('asdf')); // true

Korzystanie z Lodash:

_.isNaN(_.toNumber('1')); // false
_.isNaN(_.toNumber('asdf')); // true
Abtin Gramian
źródło
3
function isNumberCandidate(s) {
  const str = (''+ s).trim();
  if (str.length === 0) return false;
  return !isNaN(+str);
}

console.log(isNumberCandidate('1'));       // true
console.log(isNumberCandidate('a'));       // false
console.log(isNumberCandidate('000'));     // true
console.log(isNumberCandidate('1a'));      // false 
console.log(isNumberCandidate('1e'));      // false
console.log(isNumberCandidate('1e-1'));    // true
console.log(isNumberCandidate('123.3'));   // true
console.log(isNumberCandidate(''));        // false
console.log(isNumberCandidate(' '));       // false
console.log(isNumberCandidate(1));         // true
console.log(isNumberCandidate(0));         // true
console.log(isNumberCandidate(NaN));       // false
console.log(isNumberCandidate(undefined)); // false
console.log(isNumberCandidate(null));      // false
console.log(isNumberCandidate(-1));        // true
console.log(isNumberCandidate('-1'));      // true
console.log(isNumberCandidate('-1.2'));    // true
console.log(isNumberCandidate(0.0000001)); // true
console.log(isNumberCandidate('0.0000001')); // true
console.log(isNumberCandidate(Infinity));    // true
console.log(isNumberCandidate(-Infinity));    // true

console.log(isNumberCandidate('Infinity'));  // true

if (isNumberCandidate(s)) {
  // use +s as a number
  +s ...
}
gvlax
źródło
Dziękuję, świetna odpowiedź!
M.Abulsoud
3

2019: W tym przykłady ES3, ES6 i TypeScript

Może to zostało przerobione zbyt wiele razy, jednak dzisiaj również z tym walczyłem i chciałem opublikować moją odpowiedź, ponieważ nie widziałem żadnej innej odpowiedzi, która robi to tak prosto lub dokładnie:

ES3

var isNumeric = function(num){
    return (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num);  
}

ES6

const isNumeric = (num) => (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num);

Maszynopis

const isNumeric = (num: any) => (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num as number);

Wydaje się to dość proste i obejmuje wszystkie podstawy, które widziałem na wielu innych postach i wymyśliłem:

// Positive Cases
console.log(0, isNumeric(0) === true);
console.log(1, isNumeric(1) === true);
console.log(1234567890, isNumeric(1234567890) === true);
console.log('1234567890', isNumeric('1234567890') === true);
console.log('0', isNumeric('0') === true);
console.log('1', isNumeric('1') === true);
console.log('1.1', isNumeric('1.1') === true);
console.log('-1', isNumeric('-1') === true);
console.log('-1.2354', isNumeric('-1.2354') === true);
console.log('-1234567890', isNumeric('-1234567890') === true);
console.log(-1, isNumeric(-1) === true);
console.log(-32.1, isNumeric(-32.1) === true);
console.log('0x1', isNumeric('0x1') === true);  // Valid number in hex
// Negative Cases
console.log(true, isNumeric(true) === false);
console.log(false, isNumeric(false) === false);
console.log('1..1', isNumeric('1..1') === false);
console.log('1,1', isNumeric('1,1') === false);
console.log('-32.1.12', isNumeric('-32.1.12') === false);
console.log('[blank]', isNumeric('') === false);
console.log('[spaces]', isNumeric('   ') === false);
console.log('null', isNumeric(null) === false);
console.log('undefined', isNumeric(undefined) === false);
console.log([], isNumeric([]) === false);
console.log('NaN', isNumeric(NaN) === false);

Możesz również wypróbować własną isNumericfunkcję i po prostu przeoczyć te przypadki użycia i wyszukać dla wszystkich z nich „prawda”.

Lub, aby zobaczyć wartości, które zwracają:

Wyniki każdego testu dla <code> isNumeric () </code>

Jeremy
źródło
3

2019: Praktyczna i ścisła numeryczna kontrola ważności

Często „poprawna liczba” oznacza liczbę Javascript bez NaN i nieskończoności, tj. „Liczbę skończoną”.

Aby sprawdzić poprawność liczbową wartości (na przykład z zewnętrznego źródła), możesz zdefiniować styl ESlint Airbnb:

/**
 * Returns true if 'candidate' is a finite number or a string referring (not just 'including') a finite number
 * To keep in mind:
 *   Number(true) = 1
 *   Number('') = 0
 *   Number("   10  ") = 10
 *   !isNaN(true) = true
 *   parseFloat('10 a') = 10
 *
 * @param {?} candidate
 * @return {boolean}
 */
function isReferringFiniteNumber(candidate) {
  if (typeof (candidate) === 'number') return Number.isFinite(candidate);
  if (typeof (candidate) === 'string') {
    return (candidate.trim() !== '') && Number.isFinite(Number(candidate));
  }
  return false;
}

i użyj tego w ten sposób:

if (isReferringFiniteNumber(theirValue)) {
  myCheckedValue = Number(theirValue);
} else {
  console.warn('The provided value doesn\'t refer to a finite number');
}
JP Duvet
źródło
2

PFB działające rozwiązanie:

 function(check){ 
    check = check + "";
    var isNumber =   check.trim().length>0? !isNaN(check):false;
    return isNumber;
    }
Predhin
źródło
2

Zaoszczędź sobie bólu głowy związanego z próbą znalezienia „wbudowanego” rozwiązania.

Nie ma dobrej odpowiedzi, a bardzo pozytywna odpowiedź w tym wątku jest błędna.

npm install is-number

W JavaScript nie zawsze jest tak proste, jak powinno być rzetelne sprawdzenie, czy wartość jest liczbą. Devs często używają +, - lub Number () do rzutowania wartości ciągu na liczbę (na przykład, gdy wartości są zwracane z danych wejściowych użytkownika, dopasowań wyrażeń regularnych, parserów itp.). Ale istnieje wiele nieintuicyjnych przypadków krawędziowych, które dają nieoczekiwane wyniki:

console.log(+[]); //=> 0
console.log(+''); //=> 0
console.log(+'   '); //=> 0
console.log(typeof NaN); //=> 'number'
Cdeutsch
źródło
1

Niedawno napisałem artykuł o sposobach zapewnienia, że ​​zmienna jest poprawną liczbą: https://github.com/jehugaleahsa/artifacts/blob/master/2018/typescript_num_hack.md Artykuł wyjaśnia, jak zapewnić zmiennoprzecinkową lub całkowitą liczbę, jeśli to jest ważne ( +xvs ~~x).

W artykule założono, że zmienna jest na początku a stringlub a numberi trimjest dostępna / wypełniona. Nie byłoby trudno rozszerzyć go na inne typy. Oto jego mięso:

// Check for a valid float
if (x == null
    || ("" + x).trim() === ""
    || isNaN(+x)) {
    return false;  // not a float
}

// Check for a valid integer
if (x == null
    || ("" + x).trim() === ""
    || ~~x !== +x) {
    return false;  // not an integer
}
Travis Parks
źródło
1

Moja próba nieco mylącego, być może nie najlepsze rozwiązanie

function isInt(a){
    return a === ""+~~a
}


console.log(isInt('abcd'));         // false
console.log(isInt('123a'));         // false
console.log(isInt('1'));            // true
console.log(isInt('0'));            // true
console.log(isInt('-0'));           // false
console.log(isInt('01'));           // false
console.log(isInt('10'));           // true
console.log(isInt('-1234567890'));  // true
console.log(isInt(1234));           // false
console.log(isInt('123.4'));        // false
console.log(isInt(''));             // false

// other types then string returns false
console.log(isInt(5));              // false
console.log(isInt(undefined));      // false
console.log(isInt(null));           // false
console.log(isInt('0x1'));          // false
console.log(isInt(Infinity));       // false
Nieskończony
źródło
Nie jest tak źle, dwa złe, że nie działa z żadną notacją dziesiętną, taką jak (1) notacja naukowa i (2) notacja non-base-10, taka jak ósemkowa ( 042) i szesnastkowa ( 0x45f)
Domi
To nie odpowiada na pytanie o szukanie wartości liczbowej, szuka tylko int.
Jeremy,
0

W mojej aplikacji dopuszczamy tylko znaki AZ AZ i 0–9. Znalazłem powyższą odpowiedź przy użyciu „ ciąg % 1 === 0” zadziałał, chyba że ciąg zaczął się od 0xnn (jak 0x10), a następnie zwróciłby go jako wartość liczbową, gdy nie chcieliśmy. Następująca prosta pułapka w mojej kontroli numerycznej wydaje się załatwić sprawę w naszych konkretnych przypadkach.

function isStringNumeric(str_input){   
    //concat a temporary 1 during the modulus to keep a beginning hex switch combination from messing us up   
    //very simple and as long as special characters (non a-z A-Z 0-9) are trapped it is fine   
    return '1'.concat(str_input) % 1 === 0;}

Ostrzeżenie : to może wykorzystywać długotrwały błąd w JavaScript i ActionScript [Number ("1" + the_string)% 1 === 0)], nie mogę za to mówić, ale jest to dokładnie to, czego potrzebowaliśmy.

rwheadon
źródło
Dlaczego miałby to być błąd w JavaScript?
Bergi
Po prostu nie widzę tego samego zachowania z podobnym rozwiązaniem w Perlu lub C, a ponieważ nie jestem programistą języka programowania dla javascript lub ActionScript, nie wiem, czy zachowanie, którego doświadczam, jest naprawdę zamierzone.
rwheadon
Cóż, javascript jest nieco niechlujny w kwestii rzutowania typu niejawnego, ale kiedy już wiesz, że możesz łatwo zrozumieć, jak to działa. Rzucasz ciągi na liczby (wywołując % 1na nich operację numeryczną ), a to interpretuje ciąg jako literę szesnastkową lub zmiennoprzecinkową.
Bergi,
0

Moje rozwiązanie:

// returns true for positive ints; 
// no scientific notation, hexadecimals or floating point dots

var isPositiveInt = function(str) { 
   var result = true, chr;
   for (var i = 0, n = str.length; i < n; i++) {
       chr = str.charAt(i);
       if ((chr < "0" || chr > "9") && chr != ",") { //not digit or thousands separator
         result = false;
         break;
       };
       if (i == 0 && (chr == "0" || chr == ",")) {  //should not start with 0 or ,
         result = false;
         break;
       };
   };
   return result;
 };

Możesz dodać dodatkowe warunki wewnątrz pętli, aby dopasować je do konkretnych potrzeb.

Iść do
źródło
0

Możesz użyć typów, takich jak w bibliotece przepływów y, aby uzyskać statyczne sprawdzanie czasu kompilacji. Oczywiście nie jest to szczególnie przydatne do wprowadzania danych przez użytkownika.

// @flow

function acceptsNumber(value: number) {
  // ...
}

acceptsNumber(42);       // Works!
acceptsNumber(3.14);     // Works!
acceptsNumber(NaN);      // Works!
acceptsNumber(Infinity); // Works!
acceptsNumber("foo");    // Error!
Co by było fajne
źródło
0

Oto linijka służąca do sprawdzenia, czy sNumjest poprawną wartością liczbową; został przetestowany pod kątem szerokiej gamy danych wejściowych:

!isNaN(+s.replace(/\s|\$/g, ''));  // returns True if numeric value
równowaga życiowa
źródło
0

Wystarczy użyć isNaN(), to przekształci ciąg na liczbę, a jeśli uzyska prawidłowy numer , zwróci false...

isNaN("Alireza"); //return true
isNaN("123"); //return false
Alireza
źródło
0

Używam następujących:

const isNumber = s => !isNaN(+s)
haxpanel
źródło
Działa stosunkowo dobrze jest wiele przypadków, ale nie takich przypadkach 1..1, 1,1, -32.1.12, i co ważniejsze, nie powiedzie się undefinedi NaN. Jeśli zdałeś undefinedlub NaNże to zwróci ci fałszywie pozytywne powiedzenie, że to liczba.
Jeremy,