Czy ktoś wie, jak mogę sprawdzić, czy zmienna jest liczbą lub łańcuchem w JavaScript?
Czy ktoś wie, jak mogę sprawdzić, czy zmienna jest liczbą lub łańcuchem w JavaScript?
Odpowiedzi:
Jeśli masz do czynienia z notacją dosłownym, a nie konstruktorów, można użyć typeof .
typeof "Hello World"; // string
typeof 123; // number
Jeśli tworzysz liczb i ciągów za pomocą konstruktora, takie jak var foo = new String("foo")
, należy pamiętać, że typeof
może wrócić object
do foo
.
Być może bardziej niezawodną metodą sprawdzania typu byłoby użycie metody znalezionej w underscore.js (źródło adnotacji można znaleźć tutaj ),
var toString = Object.prototype.toString;
_.isString = function (obj) {
return toString.call(obj) == '[object String]';
}
Zwraca wartość logiczną true
dla następujących elementów:
_.isString("Jonathan"); // true
_.isString(new String("Jonathan")); // true
var myString = new String("stuff I like"); isString(myString)
zwracała wartość false. Ponadto nie jestem do końca pewien, jak długo trwa konwersja backgroiund, wiem, kiedy nazywam „hi” .length, „hi” zostaje przekształcony w obiekt, nie jestem pewien, jak szybko zostanie ponownie przekonwertowany lub czy jest on kiedykolwiek związany do zmiennej.
Najlepszym sposobem na to jest użycie isNaN
rzutowania typu +:
Zaktualizowana metoda all-in:
function isNumber(n) { return !isNaN(parseFloat(n)) && !isNaN(n - 0) }
To samo za pomocą wyrażenia regularnego:
function isNumber(n) { return /^-?[\d.]+(?:e-?\d+)?$/.test(n); }
------------------------
isNumber('123'); // true
isNumber('123abc'); // false
isNumber(5); // true
isNumber('q345'); // false
isNumber(null); // false
isNumber(undefined); // false
isNumber(false); // false
isNumber(' '); // false
null
jest przymuszane do 0 i zwraca wartość true dlaisNumber(null);
function is_number(n) { return /^-?[\d.]+(?:e-?\d+)?$/.test(n);}
Najlepszym sposobem, jaki znalazłem, jest sprawdzenie metody w ciągu znaków, tj .:
if (x.substring) {
// do string thing
} else{
// do other thing
}
lub jeśli chcesz zrobić coś ze sprawdzaniem liczby dla właściwości liczbowej,
if (x.toFixed) {
// do number thing
} else {
// do other thing
}
To jest coś w rodzaju „pisania kaczki”, od ciebie zależy, który sposób ma największy sens. Nie mam wystarczająco dużo karmy, aby komentować, ale typof nie powiedzie się w przypadku ciągów i liczb w pudełku, tj .:
alert(typeof new String('Hello World'));
alert(typeof new Number(5));
ostrzeże „obiekt”.
typeof
zawsze, ponieważ może zawsze sprawdzać ciąg znaków, zarówno pierwotny, jak i obiekt String. Musisz tylko przetestować metodę, która jest unikalna dla wybranego typu.
{substring:"hello"}
. Wiem, że dla moich celów właśnie przetestowałem, co konkretna operacja muszę zrobić (moduł) dla typu, który musiałem sprawdzić (moduł ciągów zwraca niezdefiniowany), a następnie sprawdziłem to, zamiast uzyskać jego typ.
Poszukujesz isNaN()
:
console.log(!isNaN(123));
console.log(!isNaN(-1.23));
console.log(!isNaN(5-2));
console.log(!isNaN(0));
console.log(!isNaN("0"));
console.log(!isNaN("2"));
console.log(!isNaN("Hello"));
console.log(!isNaN("2005/12/12"));
Zobacz JavaScript isNaN () Funkcja w MDN.
isNaN
zwraca false
za null
(ale true
za undefined
).
Sprawdź, czy wartość jest literałem ciągu lub obiektem String:
function isString(o) {
return typeof o == "string" || (typeof o == "object" && o.constructor === String);
}
Test jednostkowy:
function assertTrue(value, message) {
if (!value) {
alert("Assertion error: " + message);
}
}
function assertFalse(value, message)
{
assertTrue(!value, message);
}
assertTrue(isString("string literal"), "number literal");
assertTrue(isString(new String("String object")), "String object");
assertFalse(isString(1), "number literal");
assertFalse(isString(true), "boolean literal");
assertFalse(isString({}), "object");
Sprawdzanie numeru jest podobne:
function isNumber(o) {
return typeof o == "number" || (typeof o == "object" && o.constructor === Number);
}
function is (type, value) { return value["constructor"] === type; }
?
Od ES2015 poprawnym sposobem sprawdzenia, czy zmienna zawiera prawidłową liczbę, jest Number.isFinite(value)
Przykłady:
Number.isFinite(Infinity) // false
Number.isFinite(NaN) // false
Number.isFinite(-Infinity) // false
Number.isFinite(0) // true
Number.isFinite(2e64) // true
Number.isFinite('0') // false
Number.isFinite(null) // false
Spróbuj tego,
<script>
var regInteger = /^-?\d+$/;
function isInteger( str ) {
return regInteger.test( str );
}
if(isInteger("1a11")) {
console.log( 'Integer' );
} else {
console.log( 'Non Integer' );
}
</script>
Najlepszy sposób to zrobić:
function isNumber(num) {
return (typeof num == 'string' || typeof num == 'number') && !isNaN(num - 0) && num !== '';
};
Spełnia to następujące przypadki testowe:
assertEquals("ISNUMBER-True: 0", true, isNumber(0));
assertEquals("ISNUMBER-True: 1", true, isNumber(-1));
assertEquals("ISNUMBER-True: 2", true, isNumber(-500));
assertEquals("ISNUMBER-True: 3", true, isNumber(15000));
assertEquals("ISNUMBER-True: 4", true, isNumber(0.35));
assertEquals("ISNUMBER-True: 5", true, isNumber(-10.35));
assertEquals("ISNUMBER-True: 6", true, isNumber(2.534e25));
assertEquals("ISNUMBER-True: 7", true, isNumber('2.534e25'));
assertEquals("ISNUMBER-True: 8", true, isNumber('52334'));
assertEquals("ISNUMBER-True: 9", true, isNumber('-234'));
assertEquals("ISNUMBER-False: 0", false, isNumber(NaN));
assertEquals("ISNUMBER-False: 1", false, isNumber({}));
assertEquals("ISNUMBER-False: 2", false, isNumber([]));
assertEquals("ISNUMBER-False: 3", false, isNumber(''));
assertEquals("ISNUMBER-False: 4", false, isNumber('one'));
assertEquals("ISNUMBER-False: 5", false, isNumber(true));
assertEquals("ISNUMBER-False: 6", false, isNumber(false));
assertEquals("ISNUMBER-False: 7", false, isNumber());
assertEquals("ISNUMBER-False: 8", false, isNumber(undefined));
assertEquals("ISNUMBER-False: 9", false, isNumber(null));
//testing data types accurately in JavaScript (opposed to "typeof")
//from http://bonsaiden.github.com/JavaScript-Garden/
function is(type, obj) {
var clas = Object.prototype.toString.call(obj).slice(8, -1);
return obj !== undefined && obj !== null && clas === type;
}
//basic usage
is('String', 'test'); // true
is('Array', true); // false
Lub dostosuj, aby zwrócić nieznany typ:
function realTypeOf(obj) {
return Object.prototype.toString.call(obj).slice(8, -1);
}
//usage
realTypeOf(999); // 'Number'
Aktualizacja z 12 maja 2012: Pełny przykład w Javascript: A Better typeof .
realTypeOf
: realTypeOf(NaN) -> "Number"
takie samo zachowanie, jak typeof
uzgodniono, ale wciąż dalekie od ideału.
Oto podejście oparte na idei wymuszania wprowadzania danych na liczbę lub ciąg znaków przez dodanie zera lub ciągu zerowego, a następnie wykonanie wpisanego porównania równości.
function is_number(x) { return x === x+0; }
function is_string(x) { return x === x+""; }
Z jakiegoś niezgłębionego powodu x===x+0
wydaje się działać lepiej niż x===+x
.
Czy są jakieś przypadki, w których nie udaje się
W tej samej żyle:
function is_boolean(x) { return x === !!x; }
Wydaje się to być nieco szybsze niż którekolwiek x===true || x===false
lub typeof x==="boolean"
(i znacznie szybsze niż x===Boolean(x)
).
Potem jest też
function is_regexp(x) { return x === RegExp(x); }
Wszystko to zależy od istnienia operacji „tożsamości” specyficznej dla każdego typu, która może być zastosowana do dowolnej wartości i niezawodnie wytworzy wartość danego typu. Nie mogę wymyślić takiej operacji dla dat.
Dla NaN istnieje
function is_nan(x) { return x !== x;}
Jest to w zasadzie wersja podkreślenia, a na obecnym isNaN()
etapie jest około czterokrotnie szybsza niż , ale komentarze w źródle podkreślenia wspominają, że „NaN jest jedyną liczbą, która sama się nie równa” i dodaje kontrolę dla _.isNumber. Dlaczego? Jakie inne przedmioty nie byłyby sobie równe? Używa również podkreślenia - x !== +x
ale jaka to różnica+
tutaj zrobić?
Następnie dla paranoika:
function is_undefined(x) { return x===[][0]; }
albo to
function is_undefined(x) { return x===void(0); }
Czy możesz to po prostu podzielić przez 1?
Zakładam, że problemem byłby ciąg znaków wejściowych takich jak: „123ABG”
var Check = "123ABG"
if(Check == Check / 1)
{
alert("This IS a number \n")
}
else
{
alert("This is NOT a number \n")
}
Właśnie tak zrobiłem ostatnio.
a może po prostu:
function IsString(obj) {
return obj !== undefined && obj != null && obj.toLowerCase !== undefined;
}
Po dalszej analizie wiele miesięcy później, ta jedyna gwarancja obj
to obiekt, który ma toLowerCase
zdefiniowaną nazwę metody lub właściwości . Wstydzę się swojej odpowiedzi. Zobacz najlepiej głosowany typeof
.
Lub po prostu użyj odwrócenia isNaN()
:
if(!isNaN(data))
do something with the number
else
it is a string
I tak, korzystanie z jQuery's $.isNumeric()
daje więcej zabawy.
isNaN('123')
daje false, chociaż argument jest ciągiem liczbowym, a nie typem liczbowym
Myślę, że konwersja var na ciąg zmniejsza wydajność, przynajmniej ten test przeprowadzony w najnowszych przeglądarkach tak pokazuje.
Więc jeśli zależy Ci na wydajności, skorzystałbym z tego:
typeof str === "string" || str instanceof String
do sprawdzania, czy zmienna jest ciągiem (nawet jeśli używasz var str = new String("foo")
,str instanceof String
zwróci true).
Jeśli chodzi o sprawdzenie, czy jest to liczba, wybrałbym natywną isNaN
:; funkcjonować.
jQuery używa tego:
function isNumber(obj) {
return !isNaN( parseFloat( obj ) ) && isFinite( obj );
}
To rozwiązanie rozwiązuje wiele podniesionych tutaj problemów!
Jest to zdecydowanie najbardziej niezawodna metoda, z której dotychczas korzystałem. Nie wymyśliłem tego i nie pamiętam, gdzie go pierwotnie znalazłem. Ale działa tam, gdzie zawodzą inne techniki:
// Begin public utility /getVarType/
// Returns 'Function', 'Object', 'Array',
// 'String', 'Number', 'Boolean', or 'Undefined'
getVarType = function ( data ){
if (undefined === data ){ return 'Undefined'; }
if (data === null ){ return 'Null'; }
return {}.toString.call(data).slice(8, -1);
};
// End public utility /getVarType/
Przykład poprawności
var str = new String();
console.warn( getVarType(str) ); // Reports "String"
console.warn( typeof str ); // Reports "object"
var num = new Number();
console.warn( getVarType(num) ); // Reports "Number"
console.warn( typeof num ); // Reports "object"
var list = [];
console.warn( getVarType( list ) ); // Reports "Array"
console.warn( typeof list ); // Reports "object"
typeof
metody natywnej (0,788s w porównaniu do 1,481s) w Chrome. Jest to z pewnością akceptowalna wydajność, biorąc pod uwagę lepsze wyniki. Jak myślisz, dlaczego jest „naprawdę wolny”? Może tak jest - w IE6 / 7/8? Ale w tych przeglądarkach wszystko jest „naprawdę wolne”.
typeof
jest 100 razy szybszy, czego mi brakuje?
Jsut an FYI, jeśli używasz jQuery, masz
$.isNumeric()
poradzić sobie z tym. Więcej informacji na http://api.jquery.com/jQuery.isNumeric/
typeof w większości przypadków działa bardzo dobrze. Możesz spróbować użyć instrukcji if
if(typeof x === 'string' || typeof x === 'number') {
console.log("Your statement");
}
gdzie x to dowolna nazwa zmiennej do wyboru
najlepszy sposób, w jaki myślę o liczbach dodatnich i ujemnych, to: O'Reilly Javascript i DHTML Cookbook :
function isNumber(elem) {
var str = elem.value;
var oneDecimal = false;
var oneChar = 0;
// make sure value hasn't cast to a number data type
str = str.toString( );
for (var i = 0; i < str.length; i++) {
oneChar = str.charAt(i).charCodeAt(0);
// OK for minus sign as first character
if (oneChar = = 45) {
if (i = = 0) {
continue;
} else {
alert("Only the first character may be a minus sign.");
return false;
}
}
// OK for one decimal point
if (oneChar = = 46) {
if (!oneDecimal) {
oneDecimal = true;
continue;
} else {
alert("Only one decimal is allowed in a number.");
return false;
}
}
// characters outside of 0 through 9 not OK
if (oneChar < 48 || oneChar > 57) {
alert("Enter only numbers into the field.");
return false;
}
}
return true;
}
Errr? Wystarczy użyć wyrażeń regularnych! :)
function isInteger(val) {
return val.match(/^[0-9]$/)
}
function isFloat(val) {
return val.match(/^[0-9]*/\.[0-9]+$/)
}
ponieważ ciąg jako „1234” z typof pokaże „ciąg”, a odwrotność nigdy nie może się zdarzyć (typof 123 zawsze będzie liczbą), najlepiej jest użyć prostego wyrażenia regularnego /^\-?\d+$/.test(var)
. Lub bardziej zaawansowane dopasowanie liczb zmiennoprzecinkowych, liczb całkowitych i liczb ujemnych /^[\-\+]?[\d]+\.?(\d+)?$/
. Ważną stroną .test
jest to, że NIE rzuca wyjątku, jeśli var nie jest łańcuchem, wartość może być dowolna.
var val, regex = /^[\-\+]?[\d]+\.?(\d+)?$/;
regex.test(val) // false
val = '1234';
regex.test(val) // true
val = '-213';
regex.test(val) // true
val = '-213.2312';
regex.test(val) // true
val = '+213.2312';
regex.test(val) // true
val = 123;
regex.test(val) // true
val = new Number(123);
regex.test(val) // true
val = new String('123');
regex.test(val) // true
val = '1234e';
regex.test(val) // false
val = {};
regex.test(val) // false
val = false;
regex.test(val) // false
regex.test(undefined) // false
regex.test(null) // false
regex.test(window) // false
regex.test(document) // false
Jeśli szukasz prawdziwego typu, wystarczy sam typof.
Możesz sprawdzić typ zmiennej za pomocą typeof
operatora:
typeof variable
Poniższy kod zwraca true dla liczb i false dla czegokolwiek innego:
!isNaN(+variable);
typeof
operatora! @JustAMartin
number
ale jeśli podam „123”, „abc” lub inny cytowany literał, jest to ciąg znaków i nie ma znaczenia, czy można go parsować na liczbę, czy nie.
Za pomocą operacji XOR można wykryć liczbę lub ciąg znaków. liczba ^ 0 zawsze będzie podawać liczbę jako wynik, a ciąg ^ 0 da 0 jako wynik.
Example:
1) 2 ^ 0 = 2
2) '2' ^ 0 = 2
3) 'Str' ^ 0 = 0
Prosty i dokładny:
function isNumber(x) {
return parseFloat(x) == x
};
Przypadki testowe:
console.log('***TRUE CASES***');
console.log(isNumber(0));
console.log(isNumber(-1));
console.log(isNumber(-500));
console.log(isNumber(15000));
console.log(isNumber(0.35));
console.log(isNumber(-10.35));
console.log(isNumber(2.534e25));
console.log(isNumber('2.534e25'));
console.log(isNumber('52334'));
console.log(isNumber('-234'));
console.log(isNumber(Infinity));
console.log(isNumber(-Infinity));
console.log(isNumber('Infinity'));
console.log(isNumber('-Infinity'));
console.log('***FALSE CASES***');
console.log(isNumber(NaN));
console.log(isNumber({}));
console.log(isNumber([]));
console.log(isNumber(''));
console.log(isNumber('one'));
console.log(isNumber(true));
console.log(isNumber(false));
console.log(isNumber());
console.log(isNumber(undefined));
console.log(isNumber(null));
console.log(isNumber('-234aa'));
Bardzo późno na imprezę; jednak poniższe elementy zawsze działały dla mnie dobrze, gdy chcę sprawdzić, czy dane wejściowe są ciągiem znaków lub liczbą w jednym ujęciu.
return !!Object.prototype.toString.call(input).match(/\[object (String|Number)\]/);
Utworzono jsperf podczas sprawdzania, czy zmienna jest liczbą. Dość ciekawe! typeof faktycznie ma wydajność. Używanie typeof
do czegokolwiek innego niż liczby, ogólnie idzie o 1/3 prędkości jakovariable.constructor
ponieważ większość typów danych w javascript to Obiekty; liczby nie są!
http://jsperf.com/jemiloii-fastest-method-to-check-if-type-is-a-number
typeof variable === 'number'
| najszybszy | jeśli chcesz numer, na przykład 5, a nie „5”
typeof parseFloat(variable) === 'number'
| najszybszy | jeśli chcesz numer, taki jak 5 i „5”
isNaN()
jest wolniejszy, ale nie tak dużo wolniejszy. Miałem wielkie nadzieje parseInt
i parseFloat
były one jednak strasznie wolniejsze.
Do wykrywania liczb istotny jest następujący fragment z JavaScript: Dobre części Douglasa Crockforda:
Funkcja isFinite jest najlepszym sposobem ustalenia, czy wartość może być użyta jako liczba, ponieważ odrzuca NaN i Infinity. Niestety, isFinite spróbuje przekonwertować swój argument na liczbę, więc nie jest dobrym testem, jeśli wartość nie jest w rzeczywistości liczbą. Możesz zdefiniować własną funkcję isNumber:
var isNumber = function isNumber(value) { return typeof value === 'number' &&
isFinite(value);
};