Controlla se la variabile è numero o stringa in JavaScript


Risposte:


442

Se hai a che fare con la notazione letterale e non con i costruttori, puoi usare typeof :.

typeof "Hello World"; // string
typeof 123;           // number

Se stai creando numeri e stringhe tramite un costruttore, ad esempio var foo = new String("foo"), dovresti tenere a mente che typeofpotrebbe tornare objectper foo.

Forse un metodo più sicuro per controllare il tipo sarebbe quello di utilizzare il metodo trovato in underscore.js (la fonte annotata può essere trovata qui ),

var toString = Object.prototype.toString;

_.isString = function (obj) {
  return toString.call(obj) == '[object String]';
}

Questo restituisce un valore booleano trueper quanto segue:

_.isString("Jonathan"); // true
_.isString(new String("Jonathan")); // true

69
che dice rispettivamente "stringa" e "numero"
Thilo,

27
Questo non è corretto! Esistono due possibili rappresentazioni di una stringa. alert (typeof new String ()) produrrà "Oggetto". Peggio ancora, javascript si convertirà occasionalmente avanti e indietro tra le due rappresentazioni dietro le quinte a fini di ottimizzazione
George Mauer,

3
@George Secondo il PO, saranno testate solo le variabili esistenti.
Sampson,

3
Certo, ma dire che ho la funzione isString (str) {return typeof str === 'string'} alcuni Java-convert possono usare il mio metodo in modo che var myString = new String("stuff I like"); isString(myString)questo ritorni falso. Inoltre, non sono esattamente sicuro di quanto tempo duri la conversione di backgroiund, lo so quando chiamo "hi" .length, "hi" viene convertito in un oggetto, non sono sicuro di quanto tempo verrà riconvertito di nuovo o se questo è mai associato alla variabile.
George Mauer,

8
Vero, ma vorresti usare comunque l'oggetto String?
Félix Saparelli,

211

Il modo migliore per farlo è usare isNaN+ tipo casting:

Metodo all-in aggiornato:

function isNumber(n) { return !isNaN(parseFloat(n)) && !isNaN(n - 0) }

Lo stesso usando regex:

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

21
Sembra una buona soluzione se vuoi contare le stringhe che analizzano come numeri validi.
Trevor Burnham,

2
FYI: nullè forzato a 0 e restituisce true perisNumber(null);
Edward

1
cosa c'è che non vafunction is_number(n) { return /^-?[\d.]+(?:e-?\d+)?$/.test(n);}
OneOfOne,

1
Anche questo non riesce per una stringa come '123abc'.
ash

1
@ash Grazie, ho aggiornato la soluzione anche per questo caso.
BitOfUniverse

73

Il modo migliore che ho trovato è verificare la presenza di un metodo sulla stringa, ovvero:

if (x.substring) {
// do string thing
} else{
// do other thing
}

o se vuoi fare qualcosa con il controllo del numero per una proprietà numerica,

if (x.toFixed) {
// do number thing
} else {
// do other thing
}

Questo è un po 'come "scrivere l'anatra", dipende da te in che modo ha più senso. Non ho abbastanza karma per commentare, ma typeof non riesce per stringhe e numeri inscatolati, cioè:

alert(typeof new String('Hello World'));
alert(typeof new Number(5));

avviserà "oggetto".


2
Trovo che sia meglio di typeofcome può sempre verificare una stringa, sia essa primitiva o oggetto String. Devi solo testare un metodo unico per il tipo che desideri.
ADTC

Dal punto di vista di qualcuno che deve mantenere il codice, scegliere questo percorso potrebbe essere fonte di confusione. "Perché hanno usato la sottostringa e non hanno passato alcun valore? Quale logica aziendale mi manca qui?" Per lo meno, questo deve essere associato a un commento che spieghi la logica in questione.
Lemmings

3
@ Lemmings19 In realtà non chiama il metodo di sottostringa, controlla solo se x ha un metodo di sottostringa.
Alokito,

1
Mi piace l'idea di questo tipo di dattilografia ma questo fallirà per cose del genere {substring:"hello"}. So per i miei scopi che ho appena testato ciò che l'operazione specifica che dovevo fare (modulo) per il tipo di cui avevo bisogno per verificare (su moduli il modulo restituisce undefined) quindi ho controllato per quello invece di ottenere il suo tipo.
Tadhg McDonald-Jensen,

30

Stai cercando 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"));

Vedi JavaScript isNaN () Funzione su MDN.


3
Trovo strano che avrebbero scelto l'operazione inversa per il nome del metodo. Sembra più intuitivo chiamare isNumber ().
Nathan Taylor,

12
In realtà non è un'operazione inversa di 'isNumber'. NaN è un valore speciale di numero in javascript. isNaN converte tutto ciò che gli viene fornito in numero e verifica se il risultato è NaN o meno. Per stringhe come "25", si ottiene un risultato errato.
Chetan Sastry,

1
Ho appena provato con "25" ed è tornato falso, come mi sarei aspettato.
Jakob Gade,

2
NaN è un valore speciale nello standard IEEE 754 per l'aritmetica binaria a virgola mobile, non solo una cosa JavaScript. (Beh, per essere precisi: "9007199254740990 (ovvero, (2 ^ 53) -2) distinti valori" Not-a-Number "dello standard IEEE sono rappresentati in ECMAScript come un singolo valore NaN speciale." )
NickFitz

2
Tieni presente che isNaNrestituisce falseper null(ma trueper undefined).
Toni,

28

Verifica se il valore è un valore letterale stringa o String:

function isString(o) {
    return typeof o == "string" || (typeof o == "object" && o.constructor === String);
}

Test unitario:

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");

Il controllo di un numero è simile:

function isNumber(o) {
    return typeof o == "number" || (typeof o == "object" && o.constructor === Number);
}

1
(o.constructor === String) da solo sembra essere sufficiente, anche per i letterali di stringa.
Chris Noe,

2
Ciò causerà un'eccezione se o === null
TJ.

3
Ho adorato questa soluzione. Per evitare l'eccezione però per il caso nullo, usa o ["costruttore"] invece di o.constructor
dreamerkumar

2
@VishalKumar Quindi questo è tutto quello che bisogna: function is (type, value) { return value["constructor"] === type; }?
ceving il

22

Dal momento che ES2015 è il modo corretto per verificare se una variabile contiene un numero valido è Number.isFinite(value)

Esempi:

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

1
Questo non ha supporto su Internet Explorer. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
davedeecoder

1
Non funziona su String, che è la domanda originale.
Eric Grange,

18

Prova questo,

<script>
var regInteger = /^-?\d+$/;

function isInteger( str ) {    
    return regInteger.test( str );
}

if(isInteger("1a11")) {
   console.log( 'Integer' );
} else {
   console.log( 'Non Integer' );
}
</script>

prova "-2". restituisce false.
KChen,

1
Perché conservi (o non modifichi) una risposta che non funziona? ... Nota, anche un numero negativo può essere un numero intero.
Ason

13

Il modo migliore per farlo:

function isNumber(num) {
  return (typeof num == 'string' || typeof num == 'number') && !isNaN(num - 0) && num !== '';
};

Ciò soddisfa i seguenti casi di test:

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));

13
//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

O adattalo per restituire un tipo sconosciuto:

function realTypeOf(obj) {
    return Object.prototype.toString.call(obj).slice(8, -1);
}

//usage
realTypeOf(999); // 'Number'

Aggiornamento del 12 maggio 2012: esempio completo di Javascript: un tipo migliore .


Ancora margini di miglioramento per quanto riguarda realTypeOf: realTypeOf(NaN) -> "Number"che è lo stesso comportamento typeofconcordato ma tutt'altro che ideale.
Max

9

Ecco un approccio basato sull'idea di forzare l'input su un numero o una stringa aggiungendo zero o la stringa nulla, quindi fare un confronto di uguaglianza tipizzata.

function is_number(x) { return x === x+0;  }
function is_string(x) { return x === x+""; }

Per qualche ragione insondabile, x===x+0sembra funzionare meglio di x===+x.

Ci sono casi in cui questo fallisce?

Nella stessa vena:

function is_boolean(x) { return x === !!x; }

Questo sembra essere leggermente più veloce di uno x===true || x===falseo typeof x==="boolean"(e molto più veloce di x===Boolean(x)).

Poi c'è anche

function is_regexp(x)  { return x === RegExp(x); }

Tutto ciò dipende dall'esistenza di un'operazione di "identità" particolare per ciascun tipo che può essere applicata a qualsiasi valore e produrre in modo affidabile un valore del tipo in questione. Non riesco a pensare a una simile operazione per le date.

Per NaN, c'è

function is_nan(x) { return x !== x;}

Questa è sostanzialmente la versione di sottolineatura, e così com'è è circa quattro volte più veloce di isNaN(), ma i commenti nella fonte di sottolineatura menzionano che "NaN è l'unico numero che non eguaglia se stesso" e aggiunge un controllo per _.isNumber. Perché? Quali altri oggetti non sarebbero uguali? Inoltre, il carattere di sottolineatura usa: x !== +xma che differenza potrebbe +fare qui?

Quindi per il paranoico:

function is_undefined(x) { return x===[][0]; }

o questo

function is_undefined(x) { return x===void(0); }

1
x! == + x tenta innanzitutto di convertire x in un numero.
Adrian Bartholomew,

8

Puoi semplicemente dividerlo per 1?

Presumo che il problema sarebbe un input di stringa come: "123ABG"

var Check = "123ABG"

if(Check == Check / 1)
{
alert("This IS a number \n")
}

else
{
alert("This is NOT a number \n")
}

Solo un modo in cui l'ho fatto di recente.


Non penso che voglia che ritorni vero se è una serie di numeri. Forse usa ===
Curtis il

7

che ne dici di:

function IsString(obj) {
    return obj !== undefined && obj != null && obj.toLowerCase !== undefined;
}

Dopo un'ulteriore revisione molti mesi dopo, ciò garantisce solo che objun oggetto ha il nome del metodo o della proprietà toLowerCasedefinito. Mi vergogno della mia risposta. Si prega di vedere typeofuno dei più votati .


7

O semplicemente usa l'inversione di isNaN():

if(!isNaN(data))
  do something with the number
else
  it is a string

E sì, usare jQuery $.isNumeric()è più divertente.


isNaN('123')dà false, sebbene l'argomento sia una stringa numerica e non un tipo numerico
JustAMartin

6

Penso che la conversione del var in una stringa riduca le prestazioni, almeno questo test eseguito negli ultimi browser lo dimostra.

Quindi, se ti preoccupi delle prestazioni, lo userei:

typeof str === "string" || str instanceof String

per verificare se la variabile è una stringa (anche se si utilizza var str = new String("foo"), str instanceof Stringrestituisce true).

Per quanto riguarda il controllo se è un numero, andrei per il nativo isNaN:; funzione.


5

jQuery usa questo:

function isNumber(obj) {
  return !isNaN( parseFloat( obj ) ) && isFinite( obj );
}

4

Questa soluzione risolve molti dei problemi sollevati qui!

Questo è di gran lunga il metodo più affidabile che ho usato di gran lunga. Non l'ho inventato e non ricordo dove l'ho trovato in origine. Ma funziona dove altre tecniche falliscono:

// 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/

Esempio di correttezza

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"

2
Ed è davvero lento.

Tarazaburo, non so dove ottenere i tuoi dati, ma un piccolo benchmarking è in ordine:
Michael Mikowski,

Non lo trovo "molto lento". Testando la velocità su oltre 1 milione di iterazioni, trovo non peggio della metà della velocità del typeofmetodo nativo (0.788s contro 1.481s) su Chrome. Questa è certamente una prestazione accettabile considerando i risultati migliorati. Perché pensi che sia "molto lento?" Forse lo è - in IE6 / 7/8? Ma tutto è "molto lento" in quei browser.
Michael Mikowski,

Bene, l'ho detto perché avevo già fatto il benchmarking. Mettine uno nuovo su jsperf.com/check-typeof-number-again ed typeofè 100 volte più veloce, cosa mi sto perdendo?

Ti manca il fatto che 3m ops / s non rappresentano un problema per la maggior parte del codice quando si controlla il tipo. Non lo definirei "veramente lento" da nessuna parte. Il mio benchmark appariva così: var i, k, start = + new Date (); per (i = 0; i <1000000; i ++) {k = typeof ('pippo'); k = tipo di (123.5); }; end = + new Date (); console.log (end - start);
Michael Mikowski,


4

typeof funziona molto bene per me nella maggior parte dei casi. Puoi provare a usare un'istruzione if

if(typeof x === 'string' || typeof x === 'number') {
    console.log("Your statement");
}

dove x è un nome variabile a scelta


Cosa aggiunge questa risposta a quella più votata?
Bartek Banachewicz,

2
Semplicità e chiarezza?
Tim Erickson,

3

il modo migliore che ho trovato che pensa anche ai numeri positivi e negativi è da: O'Reilly Javascript e 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;

}


3

Errr? Usa solo espressioni regolari! :)

function isInteger(val) {
  return val.match(/^[0-9]$/)
}

function isFloat(val) {
  return val.match(/^[0-9]*/\.[0-9]+$/)
}

3

poiché una stringa come '1234' con typeof mostrerà 'string', e l'inverso non potrà mai accadere (typeof 123 sarà sempre un numero), la cosa migliore è usare una semplice regex /^\-?\d+$/.test(var). O un più avanzato per abbinare float, numeri interi e numeri negativi, /^[\-\+]?[\d]+\.?(\d+)?$/ Il lato importante .testè che NON genererà un'eccezione se var non è una stringa, il valore può essere qualsiasi cosa.

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 

Se stai cercando il tipo reale, lo farà solo typeof.


3

@La risposta di BitOfUniverse è buona e mi viene in mente un nuovo modo:

function isNum(n) {
    return !isNaN(n/0);
}

isNum('')  // false
isNum(2)   // true
isNum('2k') // false
isNum('2')  //true

So che 0non può essere un dividendo, ma qui la funzione funziona perfettamente.


2

Tipo di controllo

È possibile verificare il tipo di variabile utilizzando l' typeofoperatore:

typeof variable

Verifica del valore

Il codice seguente restituisce true per i numeri e false per qualsiasi altra cosa:

!isNaN(+variable);

var var = '123'; console.log (! isNaN (+ variabile)); dà vero anche se è una stringa e non un tipo di numero
JustAMartin

Perché "123" è un numero! Se vuoi conoscere il tipo di variabile, puoi usare facilmente l' typeofoperatore! @JustAMartin
Amir Fo

Sì, ma la domanda originale era quella di distinguere qualsiasi variabile tipizzata da stringa da variabile tipizzata da numero. '123` è ancora una stringa. Se passo 123, la risposta dovrebbe essere numberma se passo '123' o 'abc' o qualsiasi altro valore letterale tra virgolette, è una stringa e non importa se può essere analizzata in un numero o meno.
JustAMartin,

@JustAMartin Ok ho modificato la mia risposta.
Amir Fo

1

L'operazione XOR può essere utilizzata per rilevare il numero o la stringa. il numero ^ 0 fornirà sempre il numero come output e la stringa ^ 0 darà 0 come output.

Example: 
   1)  2 ^ 0 = 2
   2)  '2' ^ 0  = 2
   3)  'Str' ^ 0 = 0

1

Semplice e completo:

function isNumber(x) {
  return parseFloat(x) == x
};

Casi test:

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'));

0

Basta usare

myVar.constructor == String

o

myVar.constructor == Number

se si desidera gestire stringhe definite come oggetti o valori letterali e salvare non si desidera utilizzare una funzione di supporto.


0
function IsNumeric(num) {
    return ((num >=0 || num < 0)&& (parseInt(num)==num) );
}

0

Molto tardi alla festa; tuttavia, quanto segue ha sempre funzionato bene per me quando voglio verificare se un input è una stringa o un numero in un colpo.

return !!Object.prototype.toString.call(input).match(/\[object (String|Number)\]/);

0

Creato un jsperf sul controllo se una variabile è un numero. Abbastanza interessante! typeof ha effettivamente un uso prestazionale. Usando typeofqualsiasi cosa diversa dai numeri, generalmente va 1/3 della velocità come a variable.constructorpoiché la maggior parte dei tipi di dati in JavaScript sono Oggetti; i numeri non lo sono!

http://jsperf.com/jemiloii-fastest-method-to-check-if-type-is-a-number

typeof variable === 'number'| più veloce | se si desidera un numero, ad esempio 5, e non "5"
typeof parseFloat(variable) === 'number'| più veloce | se si desidera un numero, ad esempio 5, e "5"

isNaN()è più lento, ma non molto più lento. Avevo grandi speranze parseInte parseFloat, tuttavia, erano terribilmente più lenti.


0

Per rilevare i numeri, è rilevante il seguente passaggio da JavaScript: The Good Parts di Douglas Crockford:

La funzione isFinite è il modo migliore per determinare se un valore può essere usato come numero perché rifiuta NaN e Infinity. Sfortunatamente, isFinite tenterà di convertire il suo operando in un numero, quindi non è un buon test se un valore non è in realtà un numero. Potresti voler definire la tua funzione isNumber:

var isNumber = function isNumber(value) { return typeof value === 'number' &&
            isFinite(value);
};
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.