878

How to find that a number is float or integer?

1.25 --> float  
1 --> integer  
0 --> integer  
0.25 --> float
12
  • 55
    I understand what you're asking here, but just to be clear: <nit-pick> JavaScript does not have different integer and float numeric types. Every number in JavaScript is just a Number. </nit-pick>
    – Matt Ball
    Commented Oct 7, 2010 at 21:01
  • 5
    Is Infinityan integer or a non-integer value as far as you're concerned? The answers here are pretty evenly distributed on this score. Commented Mar 13, 2012 at 7:07
  • 14
    @MikeSamuel To be mathematically accurate: since infinity is not a real number and all integers are real numbers, Infinity cannot be considered an integer.
    – rvighne
    Commented Feb 15, 2014 at 18:54
  • 2
    @rvighne, I think we agree that the fact that the infinities and NaN are not real numbers means that IEEE-754 floats are not a subset of real numbers. All numerical analysis based on IEEE-754 has to deal with this fact. What I don't understand is how you think this fact determines how is_integral should behave w.r.t. cardinalities. Personally, I think ((x % 1) == 0) is a good proxy and is fully specified by IEEE-754, so there's no need to argue about correspondances between different number lines. Commented Feb 16, 2014 at 13:33
  • 6
    Do you consider 1.0 integer or float?
    – vol7ron
    Commented Jul 12, 2018 at 2:18

52 Answers 52

1513

check for a remainder when dividing by 1:

function isInt(n) {
   return n % 1 === 0;
}

If you don't know that the argument is a number you need two tests:

function isInt(n){
    return Number(n) === n && n % 1 === 0;
}

function isFloat(n){
    return Number(n) === n && n % 1 !== 0;
}

Update 2019 5 years after this answer was written, a solution was standardized in ECMA Script 2015. That solution is covered in this answer.

23
  • 149
    Careful, this will also return true for an empty string, a string representing an integral number, true, false, null, an empty array, an array containing a single integral number, an array containing a string representing an integral number, and maybe more. Commented Oct 8, 2010 at 16:53
  • 22
    Nice trick but not the correct answer as it fails to check empty string "" and 1.0 isInt(""); && isInt(1.0); both result in true see this demo jsbin.com/elohuq/1/edit Commented Oct 4, 2012 at 9:43
  • 9
    Ina, the use of === is encouraged over == in general, because it leads to more type safety and more predictable, uniform behaviour. As previous answerers have stated, this answer is absolutely, 100% incorrect. The values null, empty string, 1.0 and numerous others will all register incorrectly as integers (even with the === check).
    – whoblitz
    Commented Sep 11, 2013 at 2:59
  • 65
    The question was how to check if a number is an integer, not how to check any value.
    – kennebec
    Commented Oct 3, 2014 at 14:31
  • 32
    A lot of hostile comments about how it doesn't validate strings. That's not part of the OP's question. If I go onto SO to ask a question about retrieving the last element of an array and someone answers with function last (array) { return array[array.length - 1]; }, is it "just wrong" or "Worst answer on SO" because it doesn't check if the argument is an array first? Yes, good practice to check arguments, but that's developer responsibility. SO answers should be short and directly answer the question as clearly as possible.
    – M Miller
    Commented Jun 13, 2015 at 22:17
176

There is a method called Number.isInteger() which is currently implemented in everything but IE. MDN also provides a polyfill for other browsers:

Number.isInteger = Number.isInteger || function(value) {
  return typeof value === 'number' && 
    isFinite(value) && 
    Math.floor(value) === value;
};

However, for most uses cases, you are better off using Number.isSafeInteger which also checks if the value is so high/low that any decimal places would have been lost anyway. MDN has a polyfil for this as well. (You also need the isInteger pollyfill above.)

if (!Number.MAX_SAFE_INTEGER) {
    Number.MAX_SAFE_INTEGER = 9007199254740991; // Math.pow(2, 53) - 1;
}
Number.isSafeInteger = Number.isSafeInteger || function (value) {
   return Number.isInteger(value) && Math.abs(value) <= Number.MAX_SAFE_INTEGER;
};
8
  • 1
    In my opinion the best solution.
    – Automatico
    Commented Aug 29, 2015 at 19:25
  • 9
    Number.isInteger(12.0) //true (Chrome, Feb '17)
    – S Panfilov
    Commented Jan 31, 2017 at 20:11
  • 1
    This with the polyfill is the most reliable and simple solution. Commented Mar 22, 2017 at 21:17
  • 8
    @SergeyPanfilov 12.0 ∈ ℤ. Commented Aug 28, 2017 at 6:53
  • 2
    I'm unaware if the spec has changed since this answer was provided, but note that the above function is not a correct polyfill for Number.isInteger. It is, however, a correct polyfill for Number.isSafeInteger. Number.isInteger should not check whether the number is a "safe integer". See on MDN: isInteger and isSafeInteger. Commented Mar 19, 2018 at 11:43
169

Try these functions to test whether a value is a number primitive value that has no fractional part and is within the size limits of what can be represented as an exact integer.

function isFloat(n) {
    return n === +n && n !== (n|0);
}

function isInteger(n) {
    return n === +n && n === (n|0);
}
20
  • 6
    heh awesom exploit, it's pretty much mine (n===+n to check for numeric, n|0 to round), but with built-in operators. funky
    – Claudiu
    Commented Oct 7, 2010 at 21:11
  • 7
    @John Hartsock a string is never going to be a numeric value. It's a string. The point of this function is to test whether a value is a Javascript numeric value that has no fractional part and is within the size limits of what can be represented as an exact integer. If you want to check a string to see if it contains a sequence of characters that represent a number, you'd call parseFloat() first.
    – Pointy
    Commented Oct 7, 2010 at 21:23
  • 4
    @John Hartsock: it won't return true unless a number primitive was passed. I think that makes sense given the names of the functions. Anything else should be a candidate for isString, isBoolean, etc. if such functions are being written. Commented Oct 8, 2010 at 2:43
  • 5
    @Dan, Claudiu is right, ===+ was just my lazy formatting. It's fixed now, with Pointy's excellent comment added. Also, w3schools is generally considered to be inaccurate and incomplete; you probably don't want to use it for a reference. Better to stick to docs from MDN, WHATWG, W3C, and the official spec. Commented Oct 23, 2013 at 23:59
  • 8
    in javascript, bitwise operators like | (OR) only operate on signed 32-bit integers. OP does not state if the goal is to check for signed int32 values. So this won't work with out of range numbers. isInteger(5000000000) will return false which is wrong! Commented Jan 2, 2015 at 20:51
94

Why not something like this:

var isInt = function(n) { return parseInt(n) === n };
12
  • This is actually the core of a good solution for me. I needed to allow positive integers and disallow floats, strings and negative integers.
    – Imran-UK
    Commented Jul 9, 2013 at 16:48
  • 4
    This seems like a vastly better solution than the others in this thread. Could the community offer some criticism, perhaps? Commented May 5, 2014 at 18:06
  • 7
    var y = 1.00; y === parseInt(y, 10); // this returns true for me, which is not really what we want.
    – whoughton
    Commented May 31, 2014 at 19:11
  • 4
    @ekussberg: Why should that return false? 1 is an int. and 02, the second argument, is ignored. Commented Feb 28, 2016 at 20:33
  • 2
    −1 because converting a number to a string and then parsing it back to a number just to check whether that results in the same value is a ridiculous amount of complexity when all that’s really needed is to check whether a number—already in floating-point form!—is an integer.
    – wchargin
    Commented Dec 27, 2019 at 2:18
33

You can use a simple regular expression:

function isInt(value) {

    var er = /^-?[0-9]+$/;

    return er.test(value);
}

Or you can use the below functions too, according your needs. They are developed by the PHPJS Project.

is_int() => Check if variable type is integer and if its content is integer

is_float() => Check if variable type is float and if its content is float

ctype_digit() => Check if variable type is string and if its content has only decimal digits

Update 1

Now it checks negative numbers too, thanks for @ChrisBartley comment!

9
  • 1
    Perfect to test simple unsigned integers.
    – tothemario
    Commented Feb 16, 2014 at 20:25
  • 7
    One liner: /^[0-9]+$/.test(String(value))
    – tothemario
    Commented Feb 16, 2014 at 21:14
  • Shorter and slightly less readable one-liner: /^[0-9]+$/.test(''+value)
    – skeggse
    Commented Apr 18, 2014 at 20:59
  • 3
    Doesn't handle negative integers. You don't need the ternary operator either since test() returns a boolean. This should do it: return /^-?\d+$/.test(String(value)); Commented Apr 24, 2014 at 13:57
  • @ChrisBartley, Thanks! I made an update, including your credits. Please check if everything is okay now. Commented Apr 24, 2014 at 14:25
22

2022 update - We could simply use the Number's methods.

Check if integer or float : Number.isFinite(val)

Check if integer : Number.isInteger(val)

Check if float (not integer) : !Number.isInteger(val) && Number.isFinite(val)

1
  • great answer...
    – Sayan Dey
    Commented Jul 9, 2024 at 10:52
21
function isInteger(x) { return typeof x === "number" && isFinite(x) && Math.floor(x) === x; }
function isFloat(x) { return !!(x % 1); }

// give it a spin

isInteger(1.0);        // true
isFloat(1.0);          // false
isFloat(1.2);          // true
isInteger(1.2);        // false
isFloat(1);            // false
isInteger(1);          // true    
isFloat(2e+2);         // false
isInteger(2e+2);       // true
isFloat('1');          // false
isInteger('1');        // false
isFloat(NaN);          // false
isInteger(NaN);        // false
isFloat(null);         // false
isInteger(null);       // false
isFloat(undefined);    // false
isInteger(undefined);  // false
5
  • 4
    Apparently, floats that end with .0 are automatically cast to Int in JavaScript.
    – user234932
    Commented Nov 13, 2016 at 17:34
  • failed with 1.2. Always test numeric functions with 0.1 0.2 0.3 Commented Jul 20, 2017 at 12:53
  • @LukasLiesis not for me.
    – doubleOrt
    Commented Nov 24, 2017 at 22:10
  • There is no need for any of the strict equality operators here.
    – doubleOrt
    Commented Nov 24, 2017 at 22:10
  • isFloat(1563457121531) returns false
    – Aalex Gabi
    Commented Feb 3, 2020 at 9:17
19

Here are efficient functions that check if the value is a number or can be safely converted to a number:

function isNumber(value) {
    if ((undefined === value) || (null === value)) {
        return false;
    }
    if (typeof value == 'number') {
        return true;
    }
    return !isNaN(value - 0);
}

And for integers (would return false if the value is a float):

function isInteger(value) {
    if ((undefined === value) || (null === value)) {
        return false;
    }
    return value % 1 == 0;
}

The efficiency here is that parseInt (or parseNumber) are avoided when the value already is a number. Both parsing functions always convert to string first and then attempt to parse that string, which would be a waste if the value already is a number.

Thank you to the other posts here for providing further ideas for optimization!

1
  • 3
    This function fails on the empty string: isNumber('') is true. Commented Apr 16, 2013 at 14:56
12
function isInt(n) 
{
    return n != "" && !isNaN(n) && Math.round(n) == n;
}
function isFloat(n){
    return n != "" && !isNaN(n) && Math.round(n) != n;
}

works for all cases.

2
  • 3
    +1 This is good. isInt('1') returns true as expected (at least for me). Weird enough, though, this returns true to isInt([5]) as well. Didn't matter for me, but may for you, so, take care.
    – acdcjunior
    Commented Jul 3, 2013 at 14:07
  • 2
    isFloat(12.0) is false
    – django
    Commented Dec 15, 2015 at 6:21
8

How about this one?

isFloat(num) {
    return typeof num === "number" && !Number.isInteger(num);
}
2
  • Try console.log(isFloat(1.0)); results false.
    – fabpico
    Commented Mar 2, 2020 at 12:33
  • isFloat(NaN) and isFloat(Infinity) returns true :/
    – piecioshka
    Commented Jan 29, 2021 at 10:37
8

We can check by isInteger function. ie number will return true and float return false

console.log(Number.isInteger(2)),<BR>

Will return true

console.log(Number.isInteger(2.5))

Will return false

1
  • But Number.isInteger(2.0) also returns true Commented Sep 12, 2022 at 18:39
7

As others mentioned, you only have doubles in JS. So how do you define a number being an integer? Just check if the rounded number is equal to itself:

function isInteger(f) {
    return typeof(f)==="number" && Math.round(f) == f;
}
function isFloat(f) { return typeof(f)==="number" && !isInteger(f); }
3
  • 4
    Might want to check that the value is numeric... isFloat('abc') returns true Commented Oct 7, 2010 at 21:11
  • isFloat(NaN) // true
    – shime
    Commented May 7, 2014 at 22:07
  • @shime: Good catch. NaN is technically a floating point number though... depends what the use case is I suppose.
    – Claudiu
    Commented May 7, 2014 at 22:27
6

Here's what I use for integers:

Math.ceil(parseFloat(val)) === val

Short, nice :) Works all the time. This is what David Flanagan suggests if I'm not mistaken.

2
  • I like this one because it's a short, simple answer that doesn't rely on cryptic bitwise operations.
    – Jim
    Commented Jun 4, 2016 at 15:40
  • Why parseFloat ?
    – doubleOrt
    Commented Nov 24, 2017 at 22:12
6

Simple integer test:

if( n === parseInt(n) ) ...

Makes sense: if JavaScript can convert something to an integer, and by the conversion it becomes the exact same thing, then your operand was an integer.

Test cases for console:

x = 1;     x===parseInt(x); // true
x = "1";   x===parseInt(x); // false
x = 1.1;   x===parseInt(x); // false, obviously

// BUT!

x = 1.0;   x===parseInt(x); // true, because 1.0 is NOT a float!

This confuses a lot of people. Whenever something is .0, it's not a float anymore. It's an integer. Or you can just call it "a numeric thing" for there is no strict distinction like back then in C. Good old times.

So basically, all you can do is check for integer accepting the fact that 1.000 is an integer.

Interesting side note

There was a comment about huge numbers. Huge numbers mean NO problem for this approach; whenever parseInt is unable to handle the number (for it's too big) it will return something else than the actual value so the test will return FALSE. Look:

var a = 99999999999999999999;
var b = 999999999999999999999; // just one more 9 will kill the show!

var aIsInteger = (  a===parseInt(a)  )?"a is ok":"a fails";
var bIsInteger = (  b===parseInt(b)  )?"b is ok":"b fails";

alert(aIsInteger+"; "+bIsInteger);

I tested this in 2014 on IE8, then 2021 on Chrome, both returns "a is ok; b fails" which means if a number is too big, it can't be an integer anymore.

20 digits ought to be enough for anybody, to quote a classic.

10
  • This is fine if you only need to check for integral numbers (from a math POV), but if you want to make sure they actually work like integers (from a computing POV) it's going to be incorrect for huge numbers. See this comment. Commented Apr 26, 2014 at 9:46
  • Mmmmmmm... Why do you think that? I mean, if parseInt returns something and it seems equal to the variable itself, you can be sure your n truly does work as an integer. I found that 99999999999999999999 (that is, 20 times "9") is a number while adding one more "9" makes parseInt fail (returning 1). It may be browser-dependent; however, YES, there is a limit and NO, whatever is off that limit won't return true for the check above.
    – dkellner
    Commented Apr 26, 2014 at 15:04
  • What I mean is that bitwise operators (which treat numbers as 32 bit ints) won't give the expected results on numbers which can't be represented as 32 bit ints, so those numbers shouldn't be identified as ints. This is in line with how the proposed Number.isInteger works. Commented Apr 27, 2014 at 19:57
  • Something can be a true integer without being stored one specific way. I see your point but integers are integers because they don't have a fractional part and can be added/subtracted arbitrarily without getting float-like results. If you treat numbers as bitfields you're supposing something about how they're stored which is - in my opinion - a practically working but not 100% reliable way. If you're looking for "an integer stored in a certain way", well, I'm not sure there is a single-line test you can safely use on all platforms.
    – dkellner
    Commented Apr 28, 2014 at 19:32
  • Numbers which can be expressed as 32-bit ints do work 100% reliably with bitwise operators. You are not "supposing anything about how they are stored;" the numbers are converted to signed 32-bit big-endian two's complement integers, per specification. Numbers which cannot be represented in this format should not be considered integers. Again, this is in line with how Number.isInteger works. A single line test is n === (n | 0) as shown in another answer. Commented Apr 29, 2014 at 21:21
5

Any Float number with a zero decimal part (e.g. 1.0, 12.00, 0.0) are implicitly cast to Integer, so it is not possible to check if they are Float or not.

0
5
!!(24%1) // false
!!(24.2%1) // true
1
  • !!(24.0%1) is false Commented Jan 14, 2018 at 5:15
5
var isInt = function (n) { return n === (n | 0); };

Haven't had a case where this didn't do the job.

7
  • hey sorry why this returns false? console.log(isInt(7932938942839482938)); Commented Feb 8, 2014 at 16:33
  • 4
    Because that's exceeding MaxInt.
    – ankr
    Commented Feb 10, 2014 at 11:23
  • but you can set an Int max length nope? what if i dunno the int length is returned? Commented Feb 10, 2014 at 11:38
  • 1
    @ekussberg Yes because 2 is an integer and 23 is considered a second argument to the function. In javascript decimals are written using dot as separator - so it should be 2.23.
    – ankr
    Commented Jan 27, 2016 at 13:45
  • 1
    Or it's a great opportunity to learn about bitwise operations. You will gain a lot of benefit from that going forward.
    – ankr
    Commented Dec 12, 2017 at 14:04
5

Trying some of the answers here I ended up writing this solution. This works also with numbers inside a string.

function isInt(number) {
    if (!/^["|']{0,1}[-]{0,1}\d{0,}(\.{0,1}\d+)["|']{0,1}$/.test(number)) return false;
    return !(number - parseInt(number));
}

function isFloat(number) {
    if (!/^["|']{0,1}[-]{0,1}\d{0,}(\.{0,1}\d+)["|']{0,1}$/.test(number)) return false;
    return number - parseInt(number) ? true : false;
}

    var tests = {
        'integer' : 1,
        'float' : 1.1,
        'integerInString' : '5',
        'floatInString' : '5.5',
        'negativeInt' : -345,
        'negativeFloat' : -34.98,
        'negativeIntString' : '-45',
        'negativeFloatString' : '-23.09',
        'notValidFalse' : false,
        'notValidTrue' : true,
        'notValidString' : '45lorem',
        'notValidStringFloat' : '4.5lorem',
        'notValidNan' : NaN,
        'notValidObj' : {},
        'notValidArr' : [1,2],
    };

    function isInt(number) {
        if(!/^["|']{0,1}[-]{0,1}\d{0,}(\.{0,1}\d+)["|']{0,1}$/.test(number)) return false;
        return !(number - parseInt(number));
    }
    
    function isFloat(number) {
        if(!/^["|']{0,1}[-]{0,1}\d{0,}(\.{0,1}\d+)["|']{0,1}$/.test(number)) return false;
        return number - parseInt(number) ? true : false;
    }

    function testFunctions(obj) {
        var keys = Object.keys(obj);
        var values = Object.values(obj);

        values.forEach(function(element, index){
            console.log(`Is ${keys[index]} (${element}) var an integer? ${isInt(element)}`);
            console.log(`Is ${keys[index]} (${element}) var a float? ${isFloat(element)}`);
        });
    }

    testFunctions(tests);

4

It really depends on what you want to achieve. If you want to "emulate" strongly typed languages then I suggest you not trying. As others mentioned all numbers have the same representation (the same type).

Using something like Claudiu provided:

isInteger( 1.0 ) -> true

which looks fine for common sense, but in something like C you would get false

3
function isInteger(n) {
   return ((typeof n==='number')&&(n%1===0));
}

function isFloat(n) {
   return ((typeof n==='number')&&(n%1!==0));
}

function isNumber(n) {
   return (typeof n==='number');
}
1
  • An integer isn't a float? News to me. Commented Oct 16, 2014 at 20:36
3

It really doesn't have to be so complicated. The numeric value of an integer's parseFloat() and parseInt() equivalents will be the same. Thus you can do like so:

function isInt(value){ 
    return (parseFloat(value) == parseInt(value)) && !isNaN(value);
}

Then

if (isInt(x)) // do work

This will also allow for string checks and thus is not strict. If want a strong type solution (aka, wont work with strings):

function is_int(value){ return !isNaN(parseInt(value * 1) }
1
  • isInteger(12.0) is true
    – django
    Commented Dec 15, 2015 at 6:22
2

THIS IS FINAL CODE FOR CHECK BOTH INT AND FLOAT

function isInt(n) { 
   if(typeof n == 'number' && Math.Round(n) % 1 == 0) {
       return true;
   } else {
       return false;
   }
} 

OR

function isInt(n) {   
   return typeof n == 'number' && Math.Round(n) % 1 == 0;   
}   
1
  • This only tests for float if n happens to be a number Commented Jun 13, 2013 at 7:50
2

This solution worked for me.

<html>
<body>
  <form method="post" action="#">
    <input type="text" id="number_id"/>
    <input type="submit" value="send"/>
  </form>
  <p id="message"></p>
  <script>
    var flt=document.getElementById("number_id").value;
    if(isNaN(flt)==false && Number.isInteger(flt)==false)
    {
     document.getElementById("message").innerHTML="the number_id is a float ";
    }
   else 
   {
     document.getElementById("message").innerHTML="the number_id is a Integer";
   }
  </script>
</body>
</html>
2

try this

let n;
return (n = value % 1) !== 0 && !isNaN(n);

when the return value is false means the input value is float number or float string, otherwise the input value is integer numbef or integer string.

basically it needs to check the precision value for not equal to zero.

another one is to check the correct string number also.

1
  • Review: Welcome to Stack Overflow! While your answer might technically be correct, I'm failing to see how it is substantially different from other answers here. Therefore I'm voting to delete it in this case.
    – timur
    Commented Dec 26, 2019 at 12:27
2
const integerCheck = (num) => {
        const isInt = (n) => Number(n) === n && n % 1 === 0
        const isFloat = (n) => Number(n) === n && n % 1 !== 0
        return (isInt(num) || !isFloat(num))        
}
console.log( integerCheck('23.3') );
1
  • I don't understand the design philosophy here. There's no need to use lambdas at all. You're also doing many redundant calculations. There are 48 other answers here. What distinguishes this one from the others? Commented Feb 24, 2022 at 1:05
2

Compare that floor() result is not the same as ceil() result.

const isFloat = v => !isNaN(v) && Math.floor(v) !== Math.ceil(v);
> isFloat(1)
= false

> isFloat(1.1)
= true

> isFloat(42)
= false

> isFloat(84.42)
= true
2
  • Problem with this is that isFloat("myString") returns true Commented May 30, 2023 at 4:49
  • @BenA.Hilleli Thank you for informing me of this problem. I've updated the answer, can you verify this fixes the issue?
    – user20937717
    Commented Jun 22, 2023 at 5:11
1

For integers I use this

function integer_or_null(value) {
    if ((undefined === value) || (null === value)) {
        return null;
    }
    if(value % 1 != 0) {
        return null;
    }
    return value;
}
0
1

In java script all the numbers are internally 64 bit floating point, same as double in java. There are no diffrent types in javascript, all are represented by type number. Hence you wil l not be able make a instanceof check. However u can use the above solutions given to find out if it is a fractional number. designers of java script felt with a single type they can avoid numerous type cast errors.

1

For those curious, using Benchmark.js I tested the most up-voted answers (and the one posted today) on this post, here are my results:

var n = -10.4375892034758293405790;
var suite = new Benchmark.Suite;
suite
    // kennebec
    .add('0', function() {
        return n % 1 == 0;
    })
    // kennebec
    .add('1', function() {
        return typeof n === 'number' && n % 1 == 0;
    })
    // kennebec
    .add('2', function() {
        return typeof n === 'number' && parseFloat(n) == parseInt(n, 10) && !isNaN(n);
    })

    // Axle
    .add('3', function() {
        return n.toString().indexOf('.') === -1;
    })

    // Dagg Nabbit
    .add('4', function() {
        return n === +n && n === (n|0);
    })

    // warfares
    .add('5', function() {
        return parseInt(n) === n;
    })

    // Marcio Simao
    .add('6', function() {
        return /^-?[0-9]+$/.test(n.toString());
    })

    // Tal Liron
    .add('7', function() {
        if ((undefined === n) || (null === n)) {
            return false;
        }
        if (typeof n == 'number') {
            return true;
        }
        return !isNaN(n - 0);
    });

// Define logs and Run
suite.on('cycle', function(event) {
    console.log(String(event.target));
}).on('complete', function() {
    console.log('Fastest is ' + this.filter('fastest').pluck('name'));
}).run({ 'async': true });

0 x 12,832,357 ops/sec ±0.65% (90 runs sampled)
1 x 12,916,439 ops/sec ±0.62% (95 runs sampled)
2 x 2,776,583 ops/sec ±0.93% (92 runs sampled)
3 x 10,345,379 ops/sec ±0.49% (97 runs sampled)
4 x 53,766,106 ops/sec ±0.66% (93 runs sampled)
5 x 26,514,109 ops/sec ±2.72% (93 runs sampled)
6 x 10,146,270 ops/sec ±2.54% (90 runs sampled)
7 x 60,353,419 ops/sec ±0.35% (97 runs sampled)

Fastest is 7 Tal Liron
0
1

I like this little function, which will return true for both positive and negative integers:

function isInt(val) {
    return ["string","number"].indexOf(typeof(val)) > -1 && val !== '' && !isNaN(val+".0");
}

This works because 1 or "1" becomes "1.0", which isNaN() returns false on (which we then negate and return), but 1.0 or "1.0" becomes "1.0.0", while "string" becomes "string.0", neither of which are numbers, so isNaN() returns false (and, again, gets negated).

If you only want positive integers, there's this variant:

function isPositiveInt(val) {
    return ["string","number"].indexOf(typeof(val)) > -1 && val !== '' && !isNaN("0"+val);
}

or, for negative integers:

function isNegativeInt(val) {
    return `["string","number"].indexOf(typeof(val)) > -1` && val !== '' && isNaN("0"+val);
}

isPositiveInt() works by moving the concatenated numeric string ahead of the value to be tested. For example, isPositiveInt(1) results in isNaN() evaluating "01", which evaluates false. Meanwhile, isPositiveInt(-1) results in isNaN() evaluating "0-1", which evaluates true. We negate the return value and that gives us what we want. isNegativeInt() works similarly, but without negating the return value of isNaN().

Edit:

My original implementation would also return true on arrays and empty strings. This implementation doe not have that defect. It also has the benefit of returning early if val is not a string or number, or if it's an empty string, making it faster in these cases. You can further modify it by replacing the first two clauses with

typeof(val) != "number"

if you only want to match literal numbers (and not strings)

Edit:

I can't post comments yet, so I'm adding this to my answer. The benchmark posted by @Asok is very informative; however, the fastest function does not fit the requirements, as it also returns TRUE for floats, arrays, booleans, and empty strings.

I created the following test suite to test each of the functions, adding my answer to the list, as well (function 8, which parses strings, and function 9, which does not):

funcs = [
    function(n) {
        return n % 1 == 0;
    },
    function(n) {
        return typeof n === 'number' && n % 1 == 0;
    },
    function(n) {
        return typeof n === 'number' && parseFloat(n) == parseInt(n, 10) && !isNaN(n);
    },
    function(n) {
        return n.toString().indexOf('.') === -1;
    },
    function(n) {
        return n === +n && n === (n|0);
    },
    function(n) {
        return parseInt(n) === n;
    },
    function(n) {
        return /^-?[0-9]+$/.test(n.toString());
    },
    function(n) {
        if ((undefined === n) || (null === n)) {
            return false;
        }
        if (typeof n == 'number') {
            return true;
        }
        return !isNaN(n - 0);
    },
    function(n) {
        return ["string","number"].indexOf(typeof(n)) > -1 && n !== '' && !isNaN(n+".0");
    }
];
vals = [
    [1,true],
    [-1,true],
    [1.1,false],
    [-1.1,false],
    [[],false],
    [{},false],
    [true,false],
    [false,false],
    [null,false],
    ["",false],
    ["a",false],
    ["1",null],
    ["-1",null],
    ["1.1",null],
    ["-1.1",null]
];

for (var i in funcs) {
    var pass = true;
    console.log("Testing function "+i);
    for (var ii in vals) {
        var n = vals[ii][0];
        var ns;
        if (n === null) {
            ns = n+"";
        } else {
            switch (typeof(n)) {
                case "string":
                    ns = "'" + n + "'";
                    break;
                case "object":
                    ns = Object.prototype.toString.call(n);
                    break;
                default:
                    ns = n;
            }
            ns = "("+typeof(n)+") "+ns;
        }

        var x = vals[ii][1];
        var xs;
        if (x === null) {
            xs = "(ANY)";
        } else {
            switch (typeof(x)) {
                case "string":
                    xs = "'" + n + "'";
                    break;
                case "object":
                    xs = Object.prototype.toString.call(x);
                    break;
                default:
                    xs = x;
            }
            xs = "("+typeof(x)+") "+xs;
        }

        var rms;
        try {
            var r = funcs[i](n);
            var rs;
            if (r === null) {
                rs = r+"";
            } else {
                switch (typeof(r)) {
                    case "string":
                        rs = "'" + r + "'";
                        break;
                    case "object":
                        rs = Object.prototype.toString.call(r);
                        break;
                    default:
                        rs = r;
                }
                rs = "("+typeof(r)+") "+rs;
            }

            var m;
            var ms;
            if (x === null) {
                m = true;
                ms = "N/A";
            } else if (typeof(x) == 'object') {
                m = (xs === rs);
                ms = m;
            } else {
                m = (x === r);
                ms = m;
            }
            if (!m) {
                pass = false;
            }
            rms = "Result: "+rs+", Match: "+ms;
        } catch (e) {
            rms = "Test skipped; function threw exception!"
        }

        console.log("    Value: "+ns+", Expect: "+xs+", "+rms);
    }
    console.log(pass ? "PASS!" : "FAIL!");
}

I also reran the benchmark with function #8 added to the list. I won't post the result, as they're a bit embarrassing (e.g. that function is NOT fast)...

The (abridged -- I removed successful tests, since the output is quite long) results are as follows:

Testing function 0
Value: (object) [object Array], Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (boolean) true, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (boolean) false, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: null, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (string) '', Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (string) '1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
FAIL!

Testing function 1
Value: (string) '1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

Testing function 2
Value: (string) '1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

Testing function 3
Value: (object) true, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (object) false, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (boolean) [object Array], Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (boolean) [object Object], Expect: (boolean) false, Result: (boolean) true, Match: false
Value: null, Expect: (boolean) false, Test skipped; function threw exception!
Value: (string) '', Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (string) 'a', Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (string) '1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
FAIL!

Testing function 4
Value: (string) '1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

Testing function 5
Value: (string) '1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

Testing function 6
Value: null, Expect: (boolean) false, Test skipped; function threw exception!
Value: (string) '1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

Testing function 7
Value: (number) 1.1, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (number) -1.1, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (object) true, Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (boolean) [object Array], Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (boolean) [object Object], Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (string) '', Expect: (boolean) false, Result: (boolean) true, Match: false
Value: (string) '1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) true, Match: N/A
FAIL!

Testing function 8
Value: (string) '1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) true, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

Testing function 9
Value: (string) '1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
Value: (string) '-1.1', Expect: (ANY), Result: (boolean) false, Match: N/A
PASS!

I've left in failures so you can see where each function is failing, and the (string) '#' tests so you can see how each function handles integer and float values in strings, as some may want these parsed as numbers and some may not.

Out of the 10 functions tested, the ones that actually fit OP's requirements are [1,3,5,6,8,9]

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.