【问题标题】:How to check if a variable is an integer in JavaScript?如何在 JavaScript 中检查变量是否为整数?
【发布时间】:2013-01-16 04:32:21
【问题描述】:

如何在 JavaScript 中检查变量是否为整数,如果不是则抛出警报?我试过了,但它不起作用:

<html>
    <head>
        <script type="text/javascript">
            var data = 22;
            alert(NaN(data));
        </script>
    </head>
</html>

【问题讨论】:

  • 这里的一种可能是使用parseInt
  • jsben.ch/#/htLVw - 常用方法的基准
  • 这里的所有答案都已经过时了。今天,我建议坚持使用Number.isInteger,这是最简单的方式。
  • @Benjamim 如果数字是可以转换为整数的字符串怎么办?在 HTML 中一切都是字符串。所以 Number.isInteger("69") 是假的

标签: javascript


【解决方案1】:

这取决于,您是否也想将字符串转换为潜在整数?

这样就可以了:

function isInt(value) {
  return !isNaN(value) && 
         parseInt(Number(value)) == value && 
         !isNaN(parseInt(value, 10));
}

按位运算

简单的解析和检查

function isInt(value) {
  var x = parseFloat(value);
  return !isNaN(value) && (x | 0) === x;
}

短路,并保存解析操作:

function isInt(value) {
  if (isNaN(value)) {
    return false;
  }
  var x = parseFloat(value);
  return (x | 0) === x;
}

或者可能两者合二为一:

function isInt(value) {
  return !isNaN(value) && (function(x) { return (x | 0) === x; })(parseFloat(value))
}

测试:

isInt(42)        // true
isInt("42")      // true
isInt(4e2)       // true
isInt("4e2")     // true
isInt(" 1 ")     // true
isInt("")        // false
isInt("  ")      // false
isInt(42.1)      // false
isInt("1a")      // false
isInt("4e2a")    // false
isInt(null)      // false
isInt(undefined) // false
isInt(NaN)       // false

这是小提琴:http://jsfiddle.net/opfyrqwp/28/

性能

测试表明短路解决方案具有最佳性能(操作/秒)。

// Short-circuiting, and saving a parse operation
function isInt(value) {
  var x;
  if (isNaN(value)) {
    return false;
  }
  x = parseFloat(value);
  return (x | 0) === x;
}

这是一个基准: http://jsben.ch/#/htLVw

如果您喜欢更短、更钝的短路形式:

function isInt(value) {
  var x;
  return isNaN(value) ? !1 : (x = parseFloat(value), (0 | x) === x);
}

当然,我建议让缩小器来处理。

【讨论】:

  • @krisk - 支持多种解决方案。还对您提供的 4 个变体进行了快速测试:jsperf.com/tfm-is-integer - 并确定短路解决方案具有最佳性能。
  • 它在 2099999999999999 返回 false :-(
  • @jkucharovic 位或运算符是罪魁祸首。使用非按位版本将返回 true。
  • 这就是'2'。评估为真
  • @cyberwombat 是一个十进制数 2.0 :-)
【解决方案2】:

如下使用 === 运算符 (strict equality),

if (data === parseInt(data, 10))
    alert("data is integer")
else
    alert("data is not an integer")

【讨论】:

  • 如果你通过上面的代码运行你的例子,它会提醒 a 作为一个整数,而另一个不是一个整数,这是这种情况......在 NaN 的情况下, NaN 的类型也不同于pareInt()返回值的类型.....
  • 您能详细说明一下吗? “示例”仅表明使用 parseInt 产生的性能比使用 typeof 关键字和模运算符更差。但我确实明白你现在所说的 (NaN != NaN) 是什么意思
  • @connorbode 在javascript中所有数字都具有相同的类型(没有浮点数或双精度数),所以2.0 === 2 因为不必要的小数只是相同数字的不同表示,因此parseInt(2.0) === 2.0 是相当于parseInt(2) === 2 这是真的
  • @BlakeRegalia:虽然速度很快,但他的方法并没有从这个答案中传递所有可能的值:stackoverflow.com/a/14794066/843732
  • 这是个坏主意。请参阅2ality.com/2014/05/is-integer.html (1.4)。 parseInt() 强制转换为字符串,对于大量数字,它不会达到您的预期:console.log(1000000000000000000000); => 1e+21。有很多更好的方法,例如const isInteger = val =&gt; val%1==0.
【解决方案3】:

假设您对所讨论的变量一无所知,您应该采用这种方法:

if(typeof data === 'number') {
    var remainder = (data % 1);
    if(remainder === 0) {
        // yes, it is an integer
    }
    else if(isNaN(remainder)) {
        // no, data is either: NaN, Infinity, or -Infinity
    }
    else {
        // no, it is a float (still a number though)
    }
}
else {
    // no way, it is not even a number
}

简单地说:

if(typeof data==='number' && (data%1)===0) {
    // data is an integer
}

【讨论】:

  • 什么意思?这会检查 javascript 中的数据类型,"1.0" 是字符串,因此不是数字。否则1 将是一个变量的值,如果你这样设置它var my_var=1.0;,这个函数会正确地将它识别为一个整数。
  • 很快,Number.isInteger() 就可以工作了……在那之前,这是一个很好的方法
  • Number.isInteger 对我不起作用。我一定做错了什么。 Blake 的解决方案 %1 效果很好。
【解决方案4】:

Number.isInteger() 似乎是要走的路。

MDN还为不支持Number.isInteger()的浏览器提供了以下polyfill,主要是所有版本的IE。

Link to MDN page

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

【讨论】:

  • MDN在9007199254740992removed进行测试
  • 这是最直接和“正确”的答案。我的意思是,JavaScript 已经有了检查整数的方法。没必要写新的。 isNaN() 测试数字,而不是整数。
  • @globewalldesk 也许它回答了“如何检查数字是否为整数”而不是“变量是否为整数”的问题。例如。例如字符串“1”。
  • @Onkeltem Number.isInteger("1")
  • @WalterRoman 为什么?它返回false,而我期望true。例如,解析像product/24/edit 这样的字符串。解析后得到一个类似["product", 24, "edit"] 的数组,其中"24" 很可能是24 的整数。
【解决方案5】:

您可以检查数字是否有余数:

var data = 22;

if(data % 1 === 0){
   // yes it's an integer.
}

请注意,如果您的输入也可以是文本并且您想先检查它不是,那么您可以先检查类型:

var data = 22;

if(typeof data === 'number'){
     // yes it is numeric

    if(data % 1 === 0){
       // yes it's an integer.
    }
}

【讨论】:

    【解决方案6】:

    你可以使用一个简单的正则表达式:

    function isInt(value) {
        var er = /^-?[0-9]+$/;
        return er.test(value);
    }
    

    【讨论】:

    • 这是对我有用的一个,因为其他接受“2.”,包括 Number.isInteger()。我只添加了一行来删除前导零。
    【解决方案7】:

    ES6 中为 Number Object 添加了 2 个新方法。

    其中Number.isInteger()方法如果参数是整数则返回true,否则返回false。

    重要提示:对于可以表示为整数的浮点数,该方法也将返回 true。例如:5.0(因为它正好等于 5)

    示例用法:

    Number.isInteger(0);         // true
    Number.isInteger(1);         // true
    Number.isInteger(-100000);   // true
    Number.isInteger(99999999999999999999999); // true
    
    Number.isInteger(0.1);       // false
    Number.isInteger(Math.PI);   // false
    
    Number.isInteger(NaN);       // false
    Number.isInteger(Infinity);  // false
    Number.isInteger(-Infinity); // false
    Number.isInteger('10');      // false
    Number.isInteger(true);      // false
    Number.isInteger(false);     // false
    Number.isInteger([1]);       // false
    
    Number.isInteger(5.0);       // true
    Number.isInteger(5.000000000000001); // false
    Number.isInteger(5.0000000000000001); // true
    

    【讨论】:

    • 请注意 MDN 上的注释“对于可以表示为整数的浮点数,该方法也将返回 true。”。这取决于你需要什么。
    【解决方案8】:

    首先,NaN 是一个“数字”(是的,我知道这很奇怪,随它去吧),而不是一个“函数”。

    您需要检查变量的类型是否为数字,如果要检查整数,我会使用模数。

    alert(typeof data === 'number' && data%1 == 0);
    

    【讨论】:

    • 应该是:alert(typeof data == 'number' && (data == 0 || data % 1 == 0));避免被零除。
    • @Erwinus 0%1 仍然是除以 1。
    • @Phil, (0 == 0 || 0 % 1 == 0) 将评估为 true
    • 哦,顺便说一句,0 % 1 == 0 的计算结果也是true%不是除法!
    【解决方案9】:

    使用时要小心

    num % 1

    空字符串 ('') 或布尔值(真或假)将作为整数返回。你可能不想这样做

    false % 1 // true
    '' % 1 //true
    

    Number.isInteger(数据)

    Number.isInteger(22); //true
    Number.isInteger(22.2); //false
    Number.isInteger('22'); //false
    

    在浏览器中内置功能。不支持旧版浏览器

    替代方案:

    Math.round(num)=== num
    

    然而,Math.round() 对于空字符串和布尔值也会失败

    【讨论】:

      【解决方案10】:

      检查是否像海报这样的整数:

      if (+data===parseInt(data)) {return true} else {return false}
      

      注意数据前面的 +(将字符串转换为数字),而 === 表示精确。

      以下是示例:

      data=10
      +data===parseInt(data)
      true
      
      data="10"
      +data===parseInt(data)
      true
      
      data="10.2"
      +data===parseInt(data)
      false
      

      【讨论】:

      • 对于我的情况,这似乎是最聪明的解决方案(我不介意它是否是字符串中的整数)。然而:为什么不直接去return (+data===parseInt(data))
      【解决方案11】:

      ECMAScript-6 之前的最简单和最干净的解决方案(即使将字符串或 null 等非数字值传递给函数,也足够强大以返回 false)如下:

      function isInteger(x) { return (x^0) === x; } 
      

      以下解决方案也可以使用,虽然不如上面那个优雅:

      function isInteger(x) { return Math.round(x) === x; }
      

      注意在上述实现中,Math.ceil() 或 Math.floor() 可以同样有效地使用(而不是 Math.round())。

      或者:

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

      一个相当常见的错误解决方案如下:

      function isInteger(x) { return parseInt(x, 10) === x; }
      

      虽然这种基于 parseInt 的方法适用于许多 x 值,但一旦 x 变得相当大,它将无法正常工作。问题是 parseInt() 在解析数字之前将其第一个参数强制转换为字符串。因此,一旦数字变得足够大,它的字符串表示就会以指数形式呈现(例如,1e+21)。因此,parseInt() 将尝试解析 1e+21,但在到达 e 字符时将停止解析,因此返回值 1。观察:

      > String(1000000000000000000000)
      '1e+21'
      
      > parseInt(1000000000000000000000, 10)
      1
      
      > parseInt(1000000000000000000000, 10) === 1000000000000000000000
      false
      

      【讨论】:

        【解决方案12】:

        为什么没有人提到Number.isInteger()

        https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger

        非常适合我,并解决了以 NaN 开头的数字的问题。

        【讨论】:

        【解决方案13】:
        if(Number.isInteger(Number(data))){
            //-----
        }
        

        【讨论】:

        【解决方案14】:

        检查变量是否等于舍入为整数的同一个变量,如下所示:

        if(Math.round(data) != data) {
            alert("Variable is not an integer!");
        }
        

        【讨论】:

        • 您可以通过简单地将!= 更改为!== 并反转if 块来轻松解决此函数的问题,即为NaN 返回true。这是因为 NaN 是 JavaScript 中唯一不等于自身的值。例如,新代码应为if (Math.round(x) === x) { /* x IS an integer! */ }
        【解决方案15】:

        ECMA-262 6.0 (ES6) 标准包含Number.isInteger 函数。

        为了增加对旧浏览器的支持,我强烈建议使用强大且社区支持的解决方案:

        https://github.com/paulmillr/es6-shim

        这是纯 ES6 JS polyfills 库

        请注意,此库需要 es5-shim,只需遵循 README.md。

        【讨论】:

          【解决方案16】:

          使用| 运算符:

          (5.3 | 0) === 5.3 // => false
          (5.0 | 0) === 5.0 // => true
          

          因此,测试函数可能如下所示:

          var isInteger = function (value) {
            if (typeof value !== 'number') {
              return false;
            }
          
            if ((value | 0) !== value) {
              return false;
            }
          
            return true;
          };
          

          【讨论】:

            【解决方案17】:

            如果value 可能是字符串形式的整数,例如var value = "23",并且您希望其计算结果为true,您可以尝试Number.isInteger(Number(value))。避免尝试Number.isInteger(parseInt(value)),因为这并不总是返回正确的值。例如,如果 var value = "23abc" 并且您使用 parseInt 实现,它仍然会返回 true。

            但如果您想要严格的整数值,那么Number.isInteger(value) 应该可以解决问题。

            【讨论】:

            • 注意IE不支持这个;如here in the docu 所述,我的脚本因此而停止,特别是如果您正在检查的 var 未定义
            【解决方案18】:
            var x = 1.5;
            if(!isNaN(x)){
             console.log('Number');
             if(x % 1 == 0){
               console.log('Integer');
             }
            }else {
             console.log('not a number');
            }
            

            【讨论】:

            • 在 29 个答案之后,人们会期待更多的解释让您的答案脱颖而出...
            【解决方案19】:

            我的做法:

            a &gt;= 1e+21 → 仅通过 用于非常大的数字。与本讨论中提供的其他解决方案不同,这肯定会涵盖所有情况。

            a === (a|0) → 如果给定函数的参数完全与按位转换后的值相同 (===),则表示该参数是整数。

            a|0 → 为a 的任何值返回0不是一个数字,如果a 确实是一个数字,它将删除小数点后的任何内容点,所以1.0001会变成1

            function isInteger(a){
                return a >= 1e+21 ? true : a === (a|0)
            }
            
            /// tests ///////////////////////////
            [
              1,                        // true
              1000000000000000000000,   // true
              4e2,                      // true
              Infinity,                 // true
              1.0,                      // true
              1.0000000000001,          // false
              0.1,                      // false
              "0",                      // false
              "1",                      // false
              "1.1",                    // false
              NaN,                      // false
              [],                       // false
              {},                       // false
              true,                     // false
              false,                    // false
              null,                     // false
              undefined                 // false
            ].forEach( a => console.log(typeof a, a, isInteger(a)) )

            【讨论】:

            • 好主意!我也喜欢你展示了你的测试,但不幸的是这不考虑字符串值“0”。
            • 嘿@vsync,不是故意的。我最初确实赞成,但由于我之前的评论决定将其恢复。我一定是不小心双击了它什么的。
            【解决方案20】:

            大整数 (bigint) 呢?

            大多数答案在大整数(253 和更大)上失败:按位测试(例如 (x | 0) === x)、测试 typeof x === 'number'、常规 int 函数(例如 parseInt)、常规算术在大整数上失败。这可以通过使用BigInt 来解决。

            我已将几个答案编译到一个 sn-p 中以显示结果。大多数大整数完全失败,而其他工作,除非通过类型BigInt(例如1n)。我没有包含重复的答案,也遗漏了任何允许小数或不尝试测试类型的答案)

            // these all fail
            n = 1000000000000000000000000000000
            b = 1n
            
            // These all fail on large integers
            //https://stackoverflow.com/a/14636652/3600709
            console.log('fail',1,n === parseInt(n, 10))
            //https://stackoverflow.com/a/14794066/3600709
            console.log('fail',2,!isNaN(n) && parseInt(Number(n)) == n && !isNaN(parseInt(n, 10)))
            console.log('fail',2,!isNaN(n) && (parseFloat(n) | 0) === parseFloat(n))
            console.log('fail',2,!isNaN(n) && (function(x) { return (x | 0) === x; })(parseFloat(n)))
            //https://stackoverflow.com/a/21742529/3600709
            console.log('fail',3,n == ~~n)
            //https://stackoverflow.com/a/28211631/3600709
            console.log('fail',4,!isNaN(n) && parseInt(n) == parseFloat(n))
            //https://stackoverflow.com/a/41854178/3600709
            console.log('fail',5,String(parseInt(n, 10)) === String(n))
            
            // These ones work for integers, but not BigInt types (e.g. 1n)
            //https://stackoverflow.com/a/14636725/3600709
            console.log('partial',1,typeof n==='number' && (n%1)===0) // this one works
            console.log('partial',1,typeof b==='number' && (b%1)===0) // this one fails
            //https://stackoverflow.com/a/27424770/3600709
            console.log('partial',2,Number.isInteger(n)) // this one works
            console.log('partial',2,Number.isInteger(b)) // this one fails
            //https://stackoverflow.com/a/14636638/3600709
            console.log('partial',3,n % 1 === 0)
            console.log('partial',3,b % 1 === 0) // gives uncaught type on BigInt

            检查类型

            如果您真的想测试传入值的类型以确保它是整数,请改用它:

            function isInt(value) {
                try {
                    BigInt(value)
                    return !['string','object','boolean'].includes(typeof value)
                } catch(e) {
                    return false
                }
            }
            

            function isInt(value) {
                try {
                    BigInt(value)
                    return !['string','object','boolean'].includes(typeof value)
                } catch(e) {
                    return false
                }
            }
            
            console.log('--- should be false')
            console.log(isInt(undefined))
            console.log(isInt(''))
            console.log(isInt(null))
            console.log(isInt({}))
            console.log(isInt([]))
            console.log(isInt(1.1e-1))
            console.log(isInt(1.1))
            console.log(isInt(true))
            console.log(isInt(NaN))
            console.log(isInt('1'))
            console.log(isInt(function(){}))
            console.log(isInt(Infinity))
            
            console.log('--- should be true')
            console.log(isInt(10))
            console.log(isInt(0x11))
            console.log(isInt(0))
            console.log(isInt(-10000))
            console.log(isInt(100000000000000000000000000000000000000))
            console.log(isInt(1n))

            不检查类型

            如果你不关心传入的类型是否真的是boolean、string等转换成数字,那么就使用下面的:

            function isInt(value) {
                try {
                    BigInt(value)
                    return true
                } catch(e) {
                    return false
                }
            }
            

            function isInt(value) {
                try {
                    BigInt(value)
                    return true
                } catch(e) {
                    return false
                }
            }
            
            console.log('--- should be false')
            console.log(isInt(undefined))
            console.log(isInt(null))
            console.log(isInt({}))
            console.log(isInt(1.1e-1))
            console.log(isInt(1.1))
            console.log(isInt(NaN))
            console.log(isInt(function(){}))
            console.log(isInt(Infinity))
            
            console.log('--- should be true')
            console.log(isInt(10))
            console.log(isInt(0x11))
            console.log(isInt(0))
            console.log(isInt(-10000))
            console.log(isInt(100000000000000000000000000000000000000))
            console.log(isInt(1n))
            // gets converted to number
            console.log(isInt(''))
            console.log(isInt([]))
            console.log(isInt(true))
            console.log(isInt('1'))

            【讨论】:

              【解决方案21】:

              你可以使用这个功能:

              function isInteger(value) {
                  return (value == parseInt(value));
              }
              

              即使该值是包含整数值的字符串,它也会返回 true。
              因此,结果将是:

              alert(isInteger(1)); // true
              alert(isInteger(1.2)); // false
              alert(isInteger("1")); // true
              alert(isInteger("1.2")); // false
              alert(isInteger("abc")); // false
              

              【讨论】:

                【解决方案22】:

                此外,Number.isInteger()。也许Number.isSafeInteger() 是另一个选项here 使用ES6 指定的。

                在 ES6 之前的浏览器中填充 Number.isSafeInteger(..)

                Number.isSafeInteger = Number.isSafeInteger || function(num) {
                    return typeof num === "number" && 
                           isFinite(num) && 
                           Math.floor(num) === num &&
                           Math.abs( num ) <= Number.MAX_SAFE_INTEGER;
                };
                

                【讨论】:

                  【解决方案23】:

                  如果你的浏览器支持Number.isInteger()是最好的方式,如果不支持,我想有很多方法可以去:

                  function isInt1(value){
                    return (value^0) === value
                  }
                  

                  或:

                  function isInt2(value){
                    return (typeof value === 'number') && (value % 1 === 0); 
                  }
                  

                  或:

                  function isInt3(value){
                    return parseInt(value, 10) === value; 
                  }
                  

                  或:

                  function isInt4(value){
                    return Math.round(value) === value; 
                  }
                  

                  现在我们可以测试结果了:

                  var value = 1
                  isInt1(value)   // return true
                  isInt2(value)   // return true
                  isInt3(value)   // return true
                  isInt4(value)   // return true
                  
                  var value = 1.1
                  isInt1(value)   // return false
                  isInt2(value)   // return false
                  isInt3(value)   // return false
                  isInt4(value)   // return false
                  
                  var value = 1000000000000000000
                  isInt1(value)   // return false
                  isInt2(value)   // return true
                  isInt3(value)   // return false
                  isInt4(value)   // return true
                  
                  var value = undefined
                  isInt1(value)   // return false
                  isInt2(value)   // return false
                  isInt3(value)   // return false
                  isInt4(value)   // return false
                  
                  var value = '1' //number as string
                  isInt1(value)   // return false
                  isInt2(value)   // return false
                  isInt3(value)   // return false
                  isInt4(value)   // return false
                  

                  所以,所有这些方法都是可行的,但是当数量很大时,parseInt 和 ^ 运算符就不能正常工作了。

                  【讨论】:

                    【解决方案24】:

                    试试这个:

                    let number = 5;
                    if (Number.isInteger(number)) {
                        //do something
                    }
                    

                    【讨论】:

                    • Number.isInteger() 并非所有版本的 IE 浏览器都支持。
                    【解决方案25】:

                    “接受”的答案是错误的(正如下面的一些 cmets 指出的那样)。 这个修改可以让它工作:

                    if (data.toString() === parseInt(data, 10).toString())
                        alert("data is a valid integer")
                    else
                        alert("data is not a valid integer")
                    

                    【讨论】:

                      【解决方案26】:

                      您可以为此使用正则表达式:

                      function isInteger(n) {
                          return (typeof n == 'number' && /^-?\d+$/.test(n+''));
                      }
                      

                      【讨论】:

                        【解决方案27】:

                        来自http://www.toptal.com/javascript/interview-questions

                        function isInteger(x) { return (x^0) === x; } 
                        

                        发现这是最好的方法。

                        【讨论】:

                        【解决方案28】:
                        function isInteger(argument) { return argument == ~~argument; }
                        

                        用法:

                        isInteger(1);     // true<br>
                        isInteger(0.1);   // false<br>
                        isInteger("1");   // true<br>
                        isInteger("0.1"); // false<br>
                        

                        或:

                        function isInteger(argument) { return argument == argument + 0 && argument == ~~argument; }
                        

                        用法:

                        isInteger(1);     // true<br>
                        isInteger(0.1);   // false<br>
                        isInteger("1");   // false<br>
                        isInteger("0.1"); // false<br>
                        

                        【讨论】:

                        • 有趣,仅适用于小整数,在大整数上失败。 isInteger(9000000000) 返回 false。原因是按位运算符将数字视为 32 位有符号整数。
                        【解决方案29】:

                        这将解决另外一个场景(121.),末尾有一个点

                        function isInt(value) {
                                var ind = value.indexOf(".");
                                if (ind > -1) { return false; }
                        
                                if (isNaN(value)) {
                                    return false;
                                }
                        
                                var x = parseFloat(value);
                                return (x | 0) === x;
                        
                            }
                        

                        【讨论】:

                          【解决方案30】:

                          对于没有分隔符的正整数值:

                          return ( data !== '' && data === data.replace(/\D/, '') );
                          

                          测试 1.如果不是空的并且 2. 如果值等于在其值中替换非数字字符的结果。

                          【讨论】:

                            猜你喜欢
                            • 2011-04-08
                            • 2015-02-25
                            • 1970-01-01
                            • 1970-01-01
                            • 2011-09-18
                            • 2014-01-10
                            • 1970-01-01
                            • 2013-10-14
                            • 2011-01-12
                            相关资源
                            最近更新 更多