Verifique se a variável é número ou sequência em JavaScript


Respostas:


442

Se você está lidando com notação literal e não com construtores, pode usar typeof :.

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

Se você estiver criando números e seqüências de caracteres por meio de um construtor, por exemplo var foo = new String("foo"), lembre-se de que typeofpode retornar objectpara foo.

Talvez um método mais seguro de verificar o tipo seja utilizar o método encontrado em underscore.js (a fonte anotada pode ser encontrada aqui ),

var toString = Object.prototype.toString;

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

Isso retorna um booleano truepara o seguinte:

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

69
que diz "string" e "number" respectivamente
Thilo

27
Isso não está correto! Existem duas representações possíveis de uma sequência. alert (typeof new String ()) produzirá "Object". Pior, javascript, ocasionalmente, irá converter e para trás entre as duas representações nos bastidores para fins de otimização
George Mauer

3
@ George De acordo com o OP, apenas as variáveis ​​existentes serão testadas.
Sampson

3
Claro, mas digamos que eu tenho a função isString (str) {return typeof str === 'string'} alguns Java-convert podem estar usando meu método assim, então var myString = new String("stuff I like"); isString(myString)isso retorna false. Além disso, não sei exatamente quanto tempo dura a conversão do backgroiund, sei quando chamo "oi" .length, "oi" é convertido em um objeto, não tenho certeza de quanto tempo é convertido novamente ou se isso está vinculado para a variável
George Mauer

8
Verdade, mas você gostaria de usar o objeto String de qualquer maneira?
Félix Saparelli

211

A melhor maneira de fazer isso é usando a isNaNconversão de tipo +:

Método all-in atualizado:

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

O mesmo 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
Parece uma boa solução se você quiser contar seqüências que analisam como números válidos.
Trevor Burnham

2
FYI: nullé coagido a 0 e retorna true paraisNumber(null);
Edward

1
o que há de errado comfunction is_number(n) { return /^-?[\d.]+(?:e-?\d+)?$/.test(n);}
OneOfOne 29/09/2013

1
Isso também falha em uma string como '123abc'.
cinzas

1
@ash Obrigado, atualizei a solução para cobrir este caso também.
BitOfUniverse

73

A melhor maneira que eu encontrei é verificar um método na string, ou seja:

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

ou se você quiser fazer algo com o número, verifique se há uma propriedade numérica,

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

É como "digitar pato", depende de você de que maneira faz mais sentido. Não tenho karma suficiente para comentar, mas o typeof falha em seqüências de caracteres e números em caixas, ou seja:

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

alertará "objeto".


2
Acho que isso é melhor do typeofque sempre pode testar uma string, seja primitiva ou objeto String. Você só precisa testar um método exclusivo para o tipo que deseja.
ADTC

Da perspectiva de alguém que precisa manter o código, a escolha desse caminho pode ser confusa. "Por que eles usaram substring e não passaram nenhum valor? Que lógica de negócios estou perdendo aqui?" No mínimo, isso precisa ser associado a um comentário explicando a lógica envolvida.
precisa

3
@ Lemmings19 Na realidade, não chama o método de substring, apenas verifica se x tem um método de substring.
Alokito 2/17/17

1
Eu gosto da idéia desse tipo de digitação de pato, mas isso falhará em coisas como {substring:"hello"}. Eu sei que, para meus propósitos, acabei de testar o que a operação específica que eu precisava fazer (módulo) faz para o tipo que eu precisava verificar (no módulo de strings retorna indefinido) e, em seguida, verifiquei isso em vez de obter seu tipo.
Tadhg McDonald-Jensen

30

Você está procurando 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"));

Consulte Função JavaScript isNaN () em MDN.


3
Acho estranho que eles escolheriam a operação inversa para o nome do método. Parece mais intuitivo chamar isNumber ().
2113 Nathan Taylor

12
Na verdade, não é uma operação inversa de 'isNumber'. NaN é um valor especial de número em javascript. isNaN converte tudo o que lhe é fornecido em número e verifica se o resultado é NaN ou não. Para strings como "25", você obtém resultado incorreto.
Chetan Sastry

1
Acabei de testar com "25" e ele retornou falso - como eu esperaria.
Jakob Gade

2
NaN é um valor especial no padrão IEEE 754 para aritmética binária de ponto flutuante, não apenas uma coisa de JavaScript. (Bem, para ser mais preciso: "os valores 9007199254740990 (ou seja, (2 ^ 53) -2) distintos" Não é um número "do IEEE Standard são representados no ECMAScript como um único valor NaN especial. )
NickFitz

2
Lembre-se de que isNaNretorna falsepara null(mas truepara undefined).
Toni

28

Verifique se o valor é uma string literal ou um objeto String:

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

Teste de unidade:

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

A verificação de um número é semelhante:

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

1
(o.constructor === String) por si só parece suficiente, mesmo para literais de string.
21412 Chris Noe

2
Isso causará uma exceção se o === null
TJ.

3
Eu amei essa solução. Para evitar a exceção embora para o caso nulo, use o [ "construtor"] em vez de o.constructor
dreamerkumar

2
@VishalKumar Então, isso é tudo o que precisamos function is (type, value) { return value["constructor"] === type; }:?
ceving 02/12/2015

22

Desde o ES2015, a maneira correta de verificar se uma variável contém um número válido é Number.isFinite(value)

Exemplos:

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
Não funciona com String, que é a pergunta original.
22820 Eric

18

Tente isso,

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

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

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

tente '-2'. retorna falso.
KChen

1
Por que você mantém (ou não edita) uma resposta que não funciona? ... Observe que também um número negativo pode ser um número inteiro.
Ason

13

Melhor maneira de fazer isso:

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

Isso satisfaz os seguintes casos de teste:

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

Ou adapte-o para retornar um tipo desconhecido:

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

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

Atualização de 12 de maio de 2012: Exemplo completo em Javascript: Um tipo melhor de .


Ainda há espaço para melhorias em relação a realTypeOf: realTypeOf(NaN) -> "Number"qual é o mesmo comportamento typeofacordado, mas ainda longe do ideal.
Max

9

Aqui está uma abordagem baseada na idéia de coagir a entrada a um número ou sequência adicionando zero ou a sequência nula e, em seguida, faça uma comparação de igualdade digitada.

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

Por alguma razão insondável, x===x+0parece ter um desempenho melhor que x===+x.

Existem casos em que isso falha?

Na mesma veia:

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

Parece ser levemente mais rápido que um x===true || x===falseou typeof x==="boolean"(e muito mais rápido que x===Boolean(x)).

Então há também

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

Tudo isso depende da existência de uma operação de "identidade" específica para cada tipo que pode ser aplicada a qualquer valor e produzir de forma confiável um valor do tipo em questão. Não consigo pensar em tal operação para datas.

Para NaN, há

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

Esta é basicamente a versão do sublinhado e, como está, é cerca de quatro vezes mais rápida que isNaN(), mas os comentários na fonte do sublinhado mencionam que "NaN é o único número que não se iguala a si mesmo" e adiciona uma verificação para _.isNumber. Por quê? Que outros objetos não seriam iguais? Além disso, os sublinhados usam - x !== +xmas que diferença o +aqui pode fazer?

Então, para o paranóico:

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

ou isto

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

1
x! == + x tenta primeiro converter x em um número.
Adrian Bartholomew

8

Você pode dividir por 1?

Suponho que o problema seria uma entrada de string como: "123ABG"

var Check = "123ABG"

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

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

Apenas uma maneira que eu fiz isso recentemente.


Não acho que ele queira que isso retorne verdadeiro se for uma série de números. Talvez use ===
Curtis

7

uh, que tal apenas:

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

Após uma análise mais aprofundada, muitos meses depois, isso garante apenas objum objeto com o nome do método ou da propriedade toLowerCasedefinido. Tenho vergonha da minha resposta. Por favor, veja o mais votado typeof.


7

Ou apenas use o inverso de isNaN():

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

E sim, usar o jQuery's $.isNumeric()é mais divertido.


isNaN('123')dá false, embora o argumento seja uma sequência numérica e não um tipo numérico
JustAMartin 28/01

6

Eu acho que converter o var em uma string diminui o desempenho, pelo menos esse teste realizado nos navegadores mais recentes mostra isso.

Então, se você se importa com o desempenho, eu usaria isso:

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

para verificar se a variável é uma string (mesmo que você use var str = new String("foo"), str instanceof Stringretornaria true).

Quanto a verificar se é um número, eu iria para o nativo isNaN:; função.


5

O jQuery usa isso:

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

4

Esta solução resolve muitos dos problemas levantados aqui!

Este é de longe o método mais confiável que já usei. Não inventei isso e não consigo me lembrar de onde o encontrei originalmente. Mas funciona onde outras técnicas falham:

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

Exemplo de correção

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
E é muito lento.

Tarazaburo, não sei de onde você obtém seus dados, mas é necessário um pouco de benchmark:
Michael Mikowski

Eu não acho isso "muito lento". Testando a velocidade em mais de 1 milhão de iterações, acho que não é pior que a metade da velocidade do typeofmétodo nativo (0.788s vs 1.481s) no Chrome. Este certamente é um desempenho aceitável, considerando os melhores resultados. Por que você acha que é "muito lento"? Talvez seja - no IE6 / 7/8? Mas tudo é "muito lento" nesses navegadores.
Michael Mikowski

Bem, eu disse isso porque já havia feito o benchmarking. Monte um novo filhote em jsperf.com/check-typeof-number-again e typeofseja 100x mais rápido, o que estou perdendo?

Está faltando o fato de que 3m ops / s não é um problema para a maioria dos códigos ao verificar o tipo. Eu não chamaria isso de "muito lento" de forma alguma. Meu benchmark ficou assim: var i, k, start = + new Date (); for (i = 0; i <1000000; i ++) {k = typeof ('foo'); k = tipo de (123,5); }; fim = + nova data (); console.log (fim - começo);
22813 Michael Mikowski


4

typeof funciona muito bem para mim na maioria dos casos. Você pode tentar usar uma instrução if

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

onde x é qualquer nome de variável de sua escolha


O que essa resposta adiciona à mais votada?
Bartek Banachewicz 01/03

2
Simplicidade e clareza?
Tim Erickson

3

a melhor maneira que encontrei, que também pensa em números positivos e negativos, é de: 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? Basta usar expressões regulares! :)

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

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

3

como uma string como '1234' com typeof mostrará 'string' e o inverso nunca poderá ocorrer (typeof 123 sempre será número), o melhor é usar uma regex simples /^\-?\d+$/.test(var). Ou um mais avançado para combinar números flutuantes, números inteiros e negativos. /^[\-\+]?[\d]+\.?(\d+)?$/ O lado importante .testé que ele não emitirá uma exceção se o var não for uma string, o valor pode ser qualquer coisa.

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 você está procurando o tipo real, somente o typeof serve.


3

A resposta do @ BitOfUniverse é boa, e eu proponho uma nova maneira:

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

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

Eu sei 0que não pode ser dividendo, mas aqui a função funciona perfeitamente.


2

Verificação de tipo

Você pode verificar o tipo de variável usando o typeofoperador:

typeof variable

Verificação de valor

O código abaixo retorna verdadeiro para números e falso para qualquer outra coisa:

!isNaN(+variable);

variável var = '123'; console.log (! isNaN (+ variável)); dá true embora seja uma string e não um tipo de número
JustAMartin 28/01

Porque '123' é um número! Se você deseja conhecer o tipo da variável, pode usar facilmente o typeofoperador! @JustAMartin
Amir Fo

Sim, mas a pergunta original era distinguir quaisquer variáveis ​​do tipo string de variáveis ​​do tipo numérico. '123' ainda é uma string. Se eu passar 123, a resposta deve ser, numbermas se eu passar '123' ou 'abc' ou qualquer outro literal citado, é uma string e não importa se pode ser analisado em um número ou não.
JustAMartin 28/01

@JustAMartin Ok, editei minha resposta.
Amir Fo

1

A operação XOR pode ser usada para detectar número ou sequência. number ^ 0 sempre fornecerá o número como saída e a string ^ 0 fornecerá 0 como saída.

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

1

Simples e completo:

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

Casos de teste:

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 usar

myVar.constructor == String

ou

myVar.constructor == Number

se você deseja manipular cadeias definidas como objetos ou literais e salvamentos, não deseja usar uma função auxiliar.


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

0

Muito tarde para a festa; no entanto, o seguinte sempre funcionou bem para mim quando quero verificar se alguma entrada é uma sequência ou um número de uma só vez.

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

0

Criou um jsperf na verificação se uma variável é um número. Muito interessante! typeof realmente tem um uso de desempenho. Usando typeofalgo que não seja números, geralmente aumenta 1/3 da velocidade, variable.constructorjá que a maioria dos tipos de dados em javascript são objetos; números não são!

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

typeof variable === 'number'| mais rápido | se você deseja um número, como 5, e não '5'
typeof parseFloat(variable) === 'number'| mais rápido | se você quiser um número, como 5 e '5'

isNaN()é mais lento, mas não muito mais lento. Eu tinha grandes esperanças parseInte parseFloat, no entanto, elas eram terrivelmente mais lentas.


0

Para detectar números, a seguinte passagem do JavaScript: The Good Parts, de Douglas Crockford, é relevante:

A função isFinite é a melhor maneira de determinar se um valor pode ser usado como um número porque rejeita NaN e Infinity. Infelizmente, o isFinite tentará converter seu operando em um número, portanto, não é um bom teste se um valor não é realmente um número. Você pode definir sua própria função isNumber:

var isNumber = function isNumber(value) { return typeof value === 'number' &&
            isFinite(value);
};
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.