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.