Как проверить, является ли переменная целым числом в JavaScript?

405

Как проверить, является ли переменная целым числом в JavaScript, и выдать предупреждение, если это не так? Я попробовал это, но это не работает:

<html>
    <head>
        <script type="text/javascript">
            var data = 22;
            alert(NaN(data));
        </script>
    </head>
</html>
JBA
источник
2
Одна из возможностей здесь заключается в использовании parseInt.
Пол
2
jsben.ch/#/htLVw - эталон для наиболее распространенных способов сделать это
EscapeNetscape
Все ответы здесь действительно устарели. Сегодня я рекомендую придерживаться того, Number.isIntegerчто является наименее хакерским способом.
Бенджамин Грюнбаум
@ Benjamim, что если число является строкой, которая может быть преобразована в целое число? и в HTML все является строкой .. поэтому Number.isInteger ("69") является ложным
joedotnot

Ответы:

344

Используйте оператор === ( строгое равенство ), как показано ниже,

if (data === parseInt(data, 10))
    alert("data is integer")
else
    alert("data is not an integer")
pranag
источник
95
это считается NaN как целое число. также работает хуже против моего метода. jsperf.com/numbers-and-integers
Блейк Регалия
2
если вы выполняете свой пример с помощью приведенного выше кода, он выводит a как целое число, а другое как не целое число, что имеет место ... в случае NaN тип NaN также отличается от типа возвращаемого значения pareInt () .....
Пранаг
1
не могли бы вы уточнить немного? «пример» только демонстрирует, что использование parseInt дает худшую производительность, чем использование ключевого слова typeof и оператора модуля. но я понимаю, что вы имеете в виду (NaN! = NaN)
Блейк Регалия
4
@connorbode в javascript, все числа имеют одинаковый тип (нет числа с плавающей запятой или двойного числа), так 2.0 === 2как ненужный десятичный знак - это просто другое представление того же числа, что parseInt(2.0) === 2.0эквивалентно тому, parseInt(2) === 2что верно
Майкл Териот
1
@BlakeRegalia: Несмотря на высокую скорость его метод не передает все возможные значения из этого ответа: stackoverflow.com/a/14794066/843732
c00000fd
506

Это зависит от того, хотите ли вы также привести строки в качестве потенциальных целых чисел?

Это будет делать:

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/

Представление

Тестирование показывает, что решение с коротким замыканием имеет лучшую производительность (ops / sec).

// 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
@krisk - проголосовал за несколько решений. Также было проведено быстрое тестирование 4 предоставленных вами вариантов: jsperf.com/tfm-is-integer - и установлено, что решение с коротким замыканием имеет наилучшую производительность.
tfmontague
1
Возвращает false 2099999999999999: - (
jkucharovic
1
@jkucharovic побитовый оператор ИЛИ является виновником. Использование небитовой версии вернет true.
Криск
1
Это делает «2». оценить как истинный
cyberwombat
1
@cyberwombat хорошо, это десятичное число 2,0 :-)
Куба Беранек
120

Предполагая, что вы ничего не знаете о рассматриваемой переменной, вы должны использовать этот подход:

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
}
Блейк Регалия
источник
8
Что вы имеете в виду? Это проверяет типы данных в javascript, "1.0"является строкой и поэтому не является числом. В противном случае 1будет значение переменной, если вы установите ее таким образом var my_var=1.0;, которая правильно определяется этой функцией как целое число.
Блейк Регалия
4
Скоро Number.isInteger()будет работать ... до тех пор, это хороший способ сделать это
Клавдиу
Number.isInteger не работает для меня. Я должен делать что-то не так. Раствор Блейка% 1 работает отлично.
mcmacerson
104

Number.isInteger() кажется, путь.

MDN также предоставил следующий polyfill для браузеров, не поддерживающих Number.isInteger() , в основном, все версии IE.

Ссылка на страницу MDN

Number.isInteger = Number.isInteger || function(value) {
    return typeof value === "number" && 
           isFinite(value) && 
           Math.floor(value) === value;
};
Уолтер Роман
источник
2
У MDN удален
Бернхард Доблер,
2
Это самый простой и «правильный» ответ. Я имею в виду, что в JavaScript уже есть метод проверки целочисленности. Не нужно писать новый. isNaN () проверяет число, а не целочисленность.
globewalldesk
66

Вы можете проверить, есть ли у номера остаток:

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.
    }
}
нет
источник
3
@ Erwinus: запустить 0 % 1 === 0в консоли. Он возвращается trueкак 0 % 1возвращается 0.
Нет
Вы пробовали это в IE ;-)
Codebeat
1
@Erwinus: 0 % 1возвращается 0в режим совместимости IE9, IE8 и IE7.
Нет
Попробуйте это в реальном старом IE. кроме того, это всегда хороший способ программирования для проверки на ноль и не полагаться на браузер, что делать.
Codebeat
62
@Erwinus: Я думаю, что вы перепутали свои факты. Ошибка деления на ноль возникает, когда вы делите на ноль, а не когда вы делите ноль на число. Ничего общего с версией IE.
Нет
22

Вы можете использовать простое регулярное выражение:

function isInt(value) {
    var er = /^-?[0-9]+$/;
    return er.test(value);
}
Марсио Маццукато
источник
15

Во-первых, NaN - это «число» (да, я знаю, что это странно, просто катитесь с ним), а не «функция».

Вам нужно проверить, является ли тип переменной числом, и проверить целое число, я бы использовал модуль.

alert(typeof data === 'number' && data%1 == 0);
Фил
источник
2
должно быть: alert (typeof data == 'number' && (data == 0 || data% 1 == 0)); чтобы избежать деления на ноль.
Codebeat
19
@Erwinus 0% 1 по-прежнему делится на 1.
Фил
@Phil, (0 == 0 || 0 % 1 == 0)оценит true.
Tomekwi
О, кстати 0 % 1 == 0тоже оценивает true! %это не разделение!
Tomekwi
13

Будьте осторожны при использовании

число% 1

пустая строка ('') или логическое значение (истина или ложь) будут возвращаться как целое число. Вы можете не захотеть этого делать

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

Number.isInteger (данные)

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

встроенная функция в браузере. Dosnt поддерживает старые браузеры

Альтернативы:

Math.round(num)=== num

Однако Math.round () также не будет работать для пустой строки и логического значения

Джанкар Махбуб
источник
8

Чтобы проверить, хочет ли целое число, например, плакат:

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
user603749
источник
6
Это кажется самым умным решением для моего случая (где я не против, если это целое число в строке). Однако: почему бы просто не пойти return (+data===parseInt(data))?
швейцарский господин
6
if(Number.isInteger(Number(data))){
    //-----
}
гость
источник
1
Тот же комментарий, что и ниже: Не поддерживается IE и Safari .
перекрестное
@crisscross Теперь поддерживается всем, кроме IE, что важно только в том случае, если вы поддерживаете устаревшие операционные системы.
faintsignal
6

Самое простое и чистое решение до ECMAScript-6 (которое также достаточно надежно, чтобы возвращать 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
Арсен Алексанян
источник
6

Почему никто не упомянул Number.isInteger()?

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

У меня отлично работает и решает проблему с NaNначала числа.

ночью
источник
1
Обратите внимание, что это ES6, поэтому старые браузеры (например, IE <= 11) не поддерживают его. Документы выше предоставляют полифилл.
епископ
Кто-то упомянул Number.isInteger(), 3,5 года до вас: stackoverflow.com/a/27424770/5208540
Алекс Стрейджис
если мы собираемся поймать значение из входных данных, то проверьте, Number.isInteger всегда будет возвращать false, поскольку входное значение имеет строковый тип данных
Shinigamae
6

В ES6 добавлено 2 новых метода для объекта Number.

В этом метод Number.isInteger () возвращает true, если аргумент является целым числом.

Пример использования:

Number.isInteger(10);        // returns true
Number.isInteger(10.5);      // returns false
Арун Джошла
источник
4

Стандарт ECMA-262 6.0 (ES6) включает функцию Number.isInteger .

Чтобы добавить поддержку старого браузера, я настоятельно рекомендую использовать сильное и поддерживаемое сообществом решение от:

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

которая является чистой библиотекой ES6 JS polyfills .

Обратите внимание, что эта библиотека требует es5-shim, просто следуйте README.md.

gavenkoa
источник
4

Вы можете попробовать, Number.isInteger(Number(value))если это valueможет быть целое число в строковой форме, например, var value = "23"и вы хотите, чтобы это оценивалось true. Старайтесь не пытаться, Number.isInteger(parseInt(value))потому что это не всегда возвращает правильное значение. Например, если var value = "23abc"вы используете parseIntреализацию, она все равно вернет true.

Но если вы хотите строго целочисленные значения, то, вероятно, Number.isInteger(value)следует сделать свое дело.

gbozee
источник
1
Обратите внимание, что это не поддерживается IE; как указано здесь в документе, мой скрипт был остановлен из-за этого, особенно если проверяемая
переменная
4
var x = 1.5;
if(!isNaN(x)){
 console.log('Number');
 if(x % 1 == 0){
   console.log('Integer');
 }
}else {
 console.log('not a number');
}
Hemant
источник
3
После 29 ответов можно было бы ожидать немного больше объяснений, чтобы ваш ответ выделялся ...
brasofilo
3

Проверьте, равна ли переменная той же самой переменной, округленной до целого числа, например:

if(Math.round(data) != data) {
    alert("Variable is not an integer!");
}
Эллиот Бонневиль
источник
Вы можете очень легко решить проблему этой функции с возвратом trueк NaN, просто изменяя !=к !==и переворачиванию ifблоков. Это работает, потому что NaNэто единственное значение в JavaScript, которое не равно себе. Например, новый код должен бытьif (Math.round(x) === x) { /* x IS an integer! */ }
mgthomas99
3

Кроме того, Number.isInteger(). Может быть , Number.isSafeInteger()это еще один вариант здесь , используя ES6 заданные.

Чтобы заполнить Number.isSafeInteger(..)в браузерах до ES6:

Number.isSafeInteger = Number.isSafeInteger || function(num) {
    return typeof num === "number" && 
           isFinite(num) && 
           Math.floor(num) === num &&
           Math.abs( num ) <= Number.MAX_SAFE_INTEGER;
};
zangw
источник
3

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 и оператор ^ не будут работать хорошо.

Чарльз Чу
источник
3

Просто попробуйте это:

let number = 5;
if (Number.isInteger(number)) {
    //do something
}
Ян ВебДев
источник
Number.isInteger () поддерживается не во всех версиях браузеров IE.
SKR
2

Вы можете использовать эту функцию:

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
ferhrosa
источник
2

Мой подход:

a >= 1e+21Тест может пройти только для значения, которое должно быть числом и очень большим. Это наверняка охватит все случаи, в отличие от других решений, которые были представлены в этом обсуждении.

a === (a|0)Если аргумент данной функции в точности (===) совпадает с побитно-преобразованным значением, это означает, что аргумент является целым числом.

a|0будет возвращаться 0для любого значения a, которое не является числом , и если 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)) )

VSync
источник
1
Хорошая идея! Мне также нравится, что вы показали свои тесты, но, к сожалению, это не учитывает строковое значение «0».
Jammer
Привет @vsync, не намеренно. Первоначально я сделал upvote, но решил вернуть его обратно из-за моего предыдущего комментария. Я должен был случайно дважды щелкнуть по нему или что-то.
Jammer
1

Вы можете использовать регулярное выражение для этого:

function isInteger(n) {
    return (typeof n == 'number' && /^-?\d+$/.test(n+''));
}
macloving
источник
1

Используйте |оператор:

(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;
};
Голо Роден
источник
1

Это решит еще один сценарий ( 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;

    }
Мухаммед Рафик
источник
1

Для положительных целочисленных значений без разделителей:

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

Тесты 1. если не пусто и 2. если значение равно результату замены нецифрового символа в его значении.

Даниэл
источник
1

Хорошо, получил минус, потому что не описал мой пример, так что больше примеров :):

Я использую регулярное выражение и метод тестирования:

var isInteger = /^[0-9]\d*$/;

isInteger.test(123); //true
isInteger.test('123'); // true
isInteger.test('sdf'); //false
isInteger.test('123sdf'); //false

// If u want to avoid string value:
typeof testVal !== 'string' && isInteger.test(testValue);
Василий Гутник
источник
Возможно, минус, потому что тест не является функцией.
imlokesh
@imlokesh что ты имеешь в виду "не функция"? oO я написал, я использую «метод испытания».
Василий Гутник
@imlokesh нет проблем, я просто спрашиваю U, потому что я использовал его в производстве :) и я подумал, что вы нашли какую-то ошибку :)
Vasyl Gutnyk
1

Вы также можете попробовать это так

var data = 22;
if (Number.isInteger(data)) {
    console.log("integer");
 }else{
     console.log("not an integer");
 }

или

if (data === parseInt(data, 10)){
    console.log("integer");
}else{
    console.log("not an integer");
}
Адехо Эммануэль IMM
источник
Это даст неправильный результат для data=22.5;. Также у обеих ветвей есть console.log("not an integer"):: S
Colin Breame
0

Я должен был проверить, является ли переменная (строка или число) целым числом, и я использовал это условие:

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

http://jsfiddle.net/e267369d/1/

Некоторые из других ответов имеют аналогичное решение (полагаться на в parseFloatсочетании с isNaN), но мой должен быть более прямым и самоочевидным.


Изменить: я обнаружил, что мой метод не работает для строк, содержащих запятую (например, «1,2»), и я также понял, что в моем конкретном случае я хочу, чтобы функция не работала, если строка не является допустимым целым числом (должен произойти сбой на любом плавающем даже 1.0). Итак, вот моя функция Mk II:

function isInt(a){
    return !isNaN(a) && parseInt(a) == parseFloat(a) && (typeof a != 'string' || (a.indexOf('.') == -1 && a.indexOf(',') == -1));
}

http://jsfiddle.net/e267369d/3/

Конечно, если вам действительно нужна функция для принятия целочисленных значений с плавающей запятой (1.0), вы всегда можете удалить условие точки a.indexOf('.') == -1.

Jahu
источник