简体   繁体   中英

Check whether variable is number or string in JavaScript

Does anyone know how can I check whether a variable is a number or a string in JavaScript?

If you're dealing with literal notation, and not constructors, you can use typeof :.

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

If you're creating numbers and strings via a constructor, such as var foo = new String("foo") , you should keep in mind that typeof may return object for foo .

Perhaps a more foolproof method of checking the type would be to utilize the method found in underscore.js (annotated source can be found here ),

var toString = Object.prototype.toString;

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

This returns a boolean true for the following:

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

Best way to do that is using isNaN + type casting:

Updated all-in method:

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

The same using 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

The best way I have found is to either check for a method on the string, ie:

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

or if you want to do something with the number check for a number property,

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

This is sort of like "duck typing", it's up to you which way makes the most sense. I don't have enough karma to comment, but typeof fails for boxed strings and numbers, ie:

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

will alert "object".

You're looking for 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"));

See JavaScript isNaN() Function at MDN.

Since ES2015 the correct way to check if a variable holds a valid number is Number.isFinite(value)

Examples:

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

Check if the value is a string literal or String object:

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

Unit test:

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

Checking for a number is similar:

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

Try this,

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

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

if(isInteger("1a11")) {
   console.log( 'Integer' );
} else {
   console.log( 'Non Integer' );
}
</script>
//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

Or adapt it to return an unknown type:

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

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

Full example at Javascript: A Better typeof . Javascript: A Better typeof中的完整示例。

Best way to do this:

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

This satisfies the following test cases:

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

Here's an approach based on the idea of coercing the input to a number or string by adding zero or the null string, and then do a typed equality comparison.

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

For some unfathomable reason, x===x+0 seems to perform better than x===+x .

Are there any cases where this fails?

In the same vein:

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

This appears to be mildly faster than either x===true || x===false x===true || x===false or typeof x==="boolean" (and much faster than x===Boolean(x) ).

Then there's also

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

All these depend on the existence of an "identity" operation particular to each type which can be applied to any value and reliably produce a value of the type in question. I cannot think of such an operation for dates.

For NaN, there is

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

This is basically underscore's version, and as it stands is about four times faster than isNaN() , but the comments in the underscore source mention that "NaN is the only number that does not equal itself" and adds a check for _.isNumber. Why? What other objects would not equal themselves? Also, underscore uses x !== +x --but what difference could the + here make?

Then for the paranoid:

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

or this

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

Simple and thorough:

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

Test cases:

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

I think converting the var to a string decreases the performance, at least this test performed in the latest browsers shows so.

So if you care about performance, I would, I'd use this:

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

for checking if the variable is a string (even if you use var str = new String("foo") , str instanceof String would return true).

As for checking if it's a number I would go for the native: isNaN ; function.

Or just use the invert of isNaN() :

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

And yes, using jQuery's $.isNumeric() is more fun for the buck.

Can you just divide it by 1?

I assume the issue would be a string input like: "123ABG"

var Check = "123ABG"

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

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

Just a way I did it recently.

uh, how about just:

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

After further review many months later, this only guarantees obj is an object that has the method or property name toLowerCase defined. I am ashamed of my answer. Please see top-voted typeof one.

jQuery uses this:

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

This solution resolves many of the issues raised here!

This is by far the most reliable method I have used by far. I did not invent this, and cannot recall where I originally found it. But it works where other techniques fail:

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

Example of correctness

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"

Jsut an FYI, if you're using jQuery you have

$.isNumeric() 

to handle this. More details on http://api.jquery.com/jQuery.isNumeric/

注意typeof NaN是... 'number'

typeof NaN === 'number'; // true

since a string as '1234' with typeof will show 'string', and the inverse cannot ever happen (typeof 123 will always be number), the best is to use a simple regex /^\-?\d+$/.test(var) . Or a more advanced to match floats, integers and negative numbers, /^[\-\+]?[\d]+\.?(\d+)?$/ The important side of .test is that it WON'T throw an exception if the var isn't an string, the value can be anything.

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 

If you are looking for the real type, then typeof alone will do.

@BitOfUniverse's answer is good, and I come up with a new way:

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

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

I know 0 can't be dividend, but here the function works perfectly.

typeof works very well for me in most case. You can try using an if statement

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

where x is any variable name of your choice

Type checking

You can check the type of variable by using typeof operator:

typeof variable

Value checking

The code below returns true for numbers and false for anything else:

!isNaN(+variable);

the best way i found which also thinks of positive and negative numbers is from : O'Reilly Javascript and 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? Just use regular expressions! :)

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

function isFloat(val) {
  return val.match(/^[0-9]*/\.[0-9]+$/)
}
function IsNumeric(num) {
    return ((num >=0 || num < 0)&& (parseInt(num)==num) );
}

XOR operation can be used to detect number or string. number ^ 0 will always give the same number as output and string ^ 0 will give 0 as output.

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

Simply use

myVar.constructor == String

or

myVar.constructor == Number

if you want to handle strings defined as objects or literals and saves you don't want to use a helper function.

Very late to the party; however, the following has always worked well for me when I want to check whether some input is either a string or a number in one shot.

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

Created a jsperf on the checking if a variable is a number. Quite interesting! typeof actually has a performance use. Using typeof for anything other than numbers, generally goes a 1/3rd the speed as a variable.constructor since the majority of data types in javascript are Objects; numbers are not!

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

typeof variable === 'number' | fastest | if you want a number, such as 5, and not '5'
typeof parseFloat(variable) === 'number' | fastest | if you want a number, such as 5, and '5'

isNaN() is slower, but not that much slower. I had high hopes for parseInt and parseFloat , however they were horribly slower.

For detecting numbers, the following passage from JavaScript: The Good Parts by Douglas Crockford is relevant:

The isFinite function is the best way of determining whether a value can be used as a number because it rejects NaN and Infinity . Unfortunately, isFinite will attempt to convert its operand to a number, so it is not a good test if a value is not actually a number. You may want to define your own isNumber function:

var isNumber = function isNumber(value) { return typeof value === 'number' &&
            isFinite(value);
};

What do you thing about this one?

const numberOrString='10' 
const isNumber = !isNaN(numberOrString*1) 

Efficiency test<\/h1>

I know which way I'll be using...

Like others, I'm addicted to strong typing (even though I love JS)

And in my code, I happened to need to make a distinction between a number and a string, to perform 2 very different types of operations.

Rather than a spiel log:

 let int = 123, str = '123'; console.log( int.constructor===Number, str.constructor===String ); // true true console.log( typeof int === 'number', typeof str === 'number'); // true false console.log (Number(int)===int, Number(str)===str ) // true false // or: console.log (String(int)===int, String(str)===str ) // false true // the shortest: console.log( +int===int, +str===str ); // true false

I therefore mainly use, especially in ternary tests.

let res = (+X===X) ? stuff_to_do_with_a_Number(X) : stuff_to_do_with_a_String(X);

Of course, this must be handled with care.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM