Проверьте, является ли переменная числом или строкой в ​​JavaScript


Ответы:


442

Если вы имеете дело с буквенными обозначениями, а не с конструкторами, вы можете использовать typeof :.

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

Если вы создаете числа и строки с помощью конструктора, например var foo = new String("foo"), вы должны иметь в виду , что typeofможет вернуться objectкfoo .

Возможно, более надежным методом проверки типа было бы использование метода, найденного в underscore.js (аннотированный источник можно найти здесь ),

var toString = Object.prototype.toString;

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

Это возвращает логическое значение trueдля следующего:

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

69
где написано «строка» и «число» соответственно
— Thilo

27
Это не правильно! Есть два возможных представления строки. alert (typeof new String ()) выведет «Object». Хуже того, javascript будет время от времени конвертировать туда и обратно между двумя представлениями за кулисами в целях оптимизации
— Джордж Мауэр

3
@ Джордж В соответствии с ОП, будут проверяться только существующие переменные.
— Сэмпсон

3
Конечно, но, скажем, у меня есть функция isString (str) {return typeof str === 'string'}, некоторые методы Java-преобразования могут использовать мой метод, так что var myString = new String("stuff I like"); isString(myString)это возвращает false. Кроме того, я не совсем уверен, как долго длится преобразование backgroiund, я знаю, что когда я называю «hi» .length, «hi» преобразуется в объект, не уверен, как скоро он будет преобразован обратно или когда-либо будет связан к переменной.
— Джордж Мауэр

8
Верно, но вы бы хотели использовать объект String?
— Феликс Сапарелли

211

Лучший способ сделать это - использовать isNaNприведение типа +:

Обновлен метод олл-ин:

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

То же самое с использованием регулярных выражений:

function isNumber(n) { return /^-?[\d.]+(?:e-?\d+)?$/.test(n); } 

------------------------

isNumber('123'); // true  
isNumber('123abc'); // false  
isNumber(5); // true  
isNumber('q345'); // false
isNumber(null); // false
isNumber(undefined); // false
isNumber(false); // false
isNumber('   '); // false

21
Это выглядит как хорошее решение, если вы хотите считать строки, которые анализируются как действительные числа.
— Тревор Бернхем

2
К вашему сведению: nullприводится в 0 и возвращает истину дляisNumber(null);
— Эдвард

1
что не так сfunction is_number(n) { return /^-?[\d.]+(?:e-?\d+)?$/.test(n);}
— OneOfOne

1
Это также не выполняется для строки, такой как «123abc».
— пепел

1
@ash Спасибо, я обновил решение для этого случая.
— BitOfUniverse

73

Лучший способ, который я нашел, - это либо проверить метод в строке, то есть:

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

или если вы хотите что-то сделать с проверкой числа для свойства числа,

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

Это что-то вроде «утки», это зависит от вас, какой способ имеет наибольшее значение. Мне не хватает кармы, чтобы комментировать, но typeof не работает для строк и чисел в штучной упаковке, то есть:

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

предупредит "объект".


2
Я считаю, что это лучше, чем то, typeofчто он всегда может проверить строку, примитив или объект String. Вам просто нужно проверить метод, который уникален для нужного вам типа.
— ADTC

С точки зрения того, кто должен поддерживать код, выбор этого пути может привести к путанице. «Почему они используют подстроку и не передают никаких значений? Какую бизнес-логику мне здесь не хватает?» По крайней мере, это должно быть связано с комментарием, объясняющим логику.
— Lemmings19

3
@ Lemmings19 На самом деле он не вызывает метод подстроки, он только проверяет, есть ли у x метод подстроки.
— Алокито

1
Мне нравится идея такого типа утки, но это не удастся для таких вещей, как {substring:"hello"}. Я знаю, что для своих целей я только что проверил, что конкретная операция, которую мне нужно было сделать (модуль), выполняет для типа, который мне нужно проверить (в строках модуль возвращает неопределенное значение), а затем проверил это вместо получения своего типа.
— Tadhg McDonald-Jensen

30

Вы ищете 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"));

См. JavaScript isNaN () Функция в MDN.


3
Мне кажется странным, что они выбрали бы обратную операцию для имени метода. Кажется более интуитивно понятным для вызова isNumber ().
— Натан Тейлор

12
На самом деле это не обратная операция isNumber. NaN - это специальное значение числа в javascript. isNaN преобразует все предоставленные ему числа и проверяет, является ли результат NaN или нет. Для строк типа «25» вы получите неверный результат.
— Четан Шастри

1
Я только что проверил с «25», и он вернул false - как я и ожидал.
— Якоб Гэйд

2
NaN является специальным значением в стандарте IEEE 754 для двоичной арифметики с плавающей точкой, а не просто в JavaScript. (Ну, если быть точным: «9007199254740990 (то есть, (2 ^ 53) -2) различных значений« не числа »стандарта IEEE представлены в ECMAScript как одно специальное значение NaN.» )
— NickFitz

2
Имейте в виду, что isNaNвозвращается falseза null(но trueза undefined).
— Тони

28

Проверьте, является ли значение строковым литералом или объектом String:

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

Модульный тест:

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

Проверка на номер похожа:

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

1
(o.constructor === String) сам по себе кажется достаточным даже для строковых литералов.
— Крис Ноу

2
Это вызовет исключение, если o === null
— TJ.

3
Мне понравилось это решение. Чтобы избежать исключения, хотя для нулевого случая используйте o ["constructor"] вместо o.constructor
— dreamerkumar

2
@VishalKumar Так что это все , что нужно: function is (type, value) { return value["constructor"] === type; }?
— выступление

22

Начиная с ES2015, правильный способ проверить, содержит ли переменная правильное число, Number.isFinite(value)

Примеры:

Number.isFinite(Infinity)   // false
Number.isFinite(NaN)        // false
Number.isFinite(-Infinity)  // false

Number.isFinite(0)          // true
Number.isFinite(2e64)       // true

Number.isFinite('0')        // false
Number.isFinite(null)       // false

1
Это не поддерживает Internet Explorer. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
— davedeecoder

1
Не работает на String, это оригинальный вопрос.
— Эрик Грандж

18

Попробуй это,

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

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

if(isInteger("1a11")) {
   console.log( 'Integer' );
} else {
   console.log( 'Non Integer' );
}
</script>

попробуйте '-2'. это возвращает ложь.
— КЧен

1
Почему вы сохраняете (или не редактируете) ответ, который не работает? ... Обратите внимание, отрицательное число также может быть целым числом.
— Асон

13

Лучший способ сделать это:

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

Это удовлетворяет следующим тестам:

assertEquals("ISNUMBER-True: 0", true, isNumber(0));
assertEquals("ISNUMBER-True: 1", true, isNumber(-1));
assertEquals("ISNUMBER-True: 2", true, isNumber(-500));
assertEquals("ISNUMBER-True: 3", true, isNumber(15000));
assertEquals("ISNUMBER-True: 4", true, isNumber(0.35));
assertEquals("ISNUMBER-True: 5", true, isNumber(-10.35));
assertEquals("ISNUMBER-True: 6", true, isNumber(2.534e25));
assertEquals("ISNUMBER-True: 7", true, isNumber('2.534e25'));
assertEquals("ISNUMBER-True: 8", true, isNumber('52334'));
assertEquals("ISNUMBER-True: 9", true, isNumber('-234'));

assertEquals("ISNUMBER-False: 0", false, isNumber(NaN));
assertEquals("ISNUMBER-False: 1", false, isNumber({}));
assertEquals("ISNUMBER-False: 2", false, isNumber([]));
assertEquals("ISNUMBER-False: 3", false, isNumber(''));
assertEquals("ISNUMBER-False: 4", false, isNumber('one'));
assertEquals("ISNUMBER-False: 5", false, isNumber(true));
assertEquals("ISNUMBER-False: 6", false, isNumber(false));
assertEquals("ISNUMBER-False: 7", false, isNumber());
assertEquals("ISNUMBER-False: 8", false, isNumber(undefined));
assertEquals("ISNUMBER-False: 9", false, isNumber(null));

13
//testing data types accurately in JavaScript (opposed to "typeof")
//from http://bonsaiden.github.com/JavaScript-Garden/
function is(type, obj) {
    var clas = Object.prototype.toString.call(obj).slice(8, -1);
    return obj !== undefined && obj !== null && clas === type;
}

//basic usage
is('String', 'test'); // true
is('Array', true); // false

Или адаптируйте его так, чтобы он возвращал неизвестный тип:

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

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

12 мая 2012 Обновление: Полный пример на Javascript: Лучший тип .


Тем не менее возможности для улучшения в отношении realTypeOf: realTypeOf(NaN) -> "Number"что такое же поведение , как typeofсогласился , но все еще далеко от идеала.
— Макс

9

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

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

По какой-то непостижимой причине, x===x+0кажется, работает лучше, чемx===+x .

Есть ли случаи, когда это не удается?

В том же духе:

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

Это выглядит немного быстрее, чем либо, x===true || x===falseлибо typeof x==="boolean"(и гораздо быстрее, чемx===Boolean(x) ).

Тогда есть также

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

Все это зависит от существования операции «идентификация», специфичной для каждого типа, которая может применяться к любому значению и надежно генерировать значение рассматриваемого типа. Я не могу думать о такой операции для дат.

Для NaN есть

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

Это в основном версия подчеркивания, и в нынешнем виде она примерно в четыре раза быстрее isNaN(), но комментарии в источнике подчеркивания упоминают, что «NaN - это единственное число, которое не равно себе», и добавляет проверку для _.isNumber. Почему? Какие другие объекты не будут равны себе? Кроме того, подчеркивание использует - x !== +xно какая разница может+ изменить здесь?

Тогда для параноика:

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

или это

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

1
x! == + x сначала пытается преобразовать x в число.
— Адриан Варфоломей

8

Вы можете просто разделить его на 1?

Я предполагаю, что проблема заключалась бы в строковом вводе типа: «123ABG»

var Check = "123ABG"

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

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

Просто так, как я это сделал недавно.


Я не думаю, что он хочет, чтобы он возвращал истину, если это строка чисел. Может быть, использовать ===
— Кертис

7

ну как насчет просто:

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

После дальнейшего рассмотрения спустя много месяцев, это только гарантирует obj, что объект, для которого toLowerCaseопределено имя метода или свойства . Мне стыдно за мой ответ. Пожалуйста, смотрите один из лучших typeof.


7

Или просто используйте инверсию isNaN():

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

И да, использование jQuery $.isNumeric()более приятное занятие.


isNaN('123')дает false, хотя аргумент является числовой строкой, а не числовым типом
— JustAMartin

6

Я думаю, что преобразование var в строку снижает производительность, по крайней мере, этот тест, выполненный в последних браузерах, показывает это.

Так что если вы заботитесь о производительности, я бы использовал это:

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

для проверки, является ли переменная строкой (даже если вы используете var str = new String("foo"), str instanceof Stringвернет true).

Что касается проверки, если это число, я бы пошел на родной isNaN:; функция.



4

Это решение решает многие проблемы, поднятые здесь!

Это, безусловно, самый надежный метод, который я когда-либо использовал. Я не изобрел это, и не могу вспомнить, где я первоначально нашел это. Но это работает там, где другие методы не работают:

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

Пример правильности

var str = new String();
console.warn( getVarType(str) ); // Reports "String"    
console.warn( typeof str );      // Reports "object"

var num = new Number();
console.warn( getVarType(num) ); // Reports "Number"
console.warn( typeof num );      // Reports "object"

var list = [];
console.warn( getVarType( list ) ); // Reports "Array"
console.warn( typeof list );        // Reports "object"

2
И это действительно медленно.

Таразабуро, я не знаю, где вы берете свои данные, но небольшой эталонный тест в порядке:
— Майкл Миковски

Я не нахожу это "очень медленным". Тестируя скорость более 1 миллиона итераций, я обнаружил, что она не хуже половины скорости нативного typeofметода (0,788 с против 1,481 с) в Chrome. Это, безусловно, приемлемая производительность, учитывая улучшенные результаты. Почему вы думаете, что это "очень медленно?" Может быть, это - в IE6 / 7/8? Но все "очень медленно" в этих браузерах.
— Майкл Миковски

Ну, я сказал это, потому что я уже сделал бенчмаркинг. Соберите нового малыша на jsperf.com/check-typeof-number-again , и он typeofбудет в 100 раз быстрее, чего мне не хватает?

Вы упускаете тот факт, что 3m ops / s не является проблемой для большинства кода при проверке типа. Я бы не назвал это «очень медленным». Мой тест выглядел так: var i, k, start = + new Date (); для (i = 0; i <1000000; i ++) {k = typeof ('foo'); k = typeof (123,5); }; конец = + новая дата (); console.log (конец - начало);
— Михаил Миковский


4

Typeof работает очень хорошо для меня в большинстве случаев. Вы можете попробовать использовать оператор if

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

где x - любое имя переменной по вашему выбору


Что этот ответ добавляет к наиболее проголосовавшему?
— Бартек Банахевич

2
Простота и ясность?
— Тим Эриксон,

3

лучший способ, который я нашел, который также думает о положительных и отрицательных числах, от: O'Reilly Javascript и DHTML Cookbook :

function isNumber(elem) {
var str = elem.value;
var oneDecimal = false;
var oneChar = 0;
// make sure value hasn't cast to a number data type
str = str.toString( );
for (var i = 0; i < str.length; i++) {
    oneChar = str.charAt(i).charCodeAt(0);
    // OK for minus sign as first character
    if (oneChar =  = 45) {
        if (i =  = 0) {
            continue;
        } else {
            alert("Only the first character may be a minus sign.");
            return false;
        }
    }
    // OK for one decimal point
    if (oneChar =  = 46) {
        if (!oneDecimal) {
            oneDecimal = true;
            continue;
        } else {
            alert("Only one decimal is allowed in a number.");
            return false;
        }
    }
    // characters outside of 0 through 9 not OK
    if (oneChar < 48 || oneChar > 57) {
        alert("Enter only numbers into the field.");
        return false;
    }
}
return true;

}


3

Errr? Просто используйте регулярные выражения! :)

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

function isFloat(val) {
  return val.match(/^[0-9]*/\.[0-9]+$/)
}

3

поскольку строка типа '1234' с typeof будет показывать 'string', а обратное никогда не произойдет (typeof 123 всегда будет числом), лучше всего использовать простое регулярное выражение /^\-?\d+$/.test(var). Или более продвинутый, чтобы соответствовать числам с плавающей запятой, целым числам и отрицательным числам /^[\-\+]?[\d]+\.?(\d+)?$/ . Важной стороной .testявляется то, что он не выдаст исключение, если переменная не является строкой, значение может быть любым.

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 

Если вы ищете реальный тип, тогда подойдет только typeof.


3

Ответ @ BitOfUniverse хорош, и я придумываю новый способ:

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

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

Я знаю, что 0не может быть дивидендов, но здесь функция работает отлично.


2

Проверка типа

Вы можете проверить тип переменной с помощью typeofоператора:

typeof variable

Проверка значения

Код ниже возвращает true для чисел и false для всего остального:

!isNaN(+variable);

переменная переменная = '123'; console.log (! IsNaN (+ переменная)); дает истину, хотя это строка, а не числовой тип
— JustAMartin

Потому что «123» - это число! Если вы хотите узнать тип переменной, вы можете легко использовать typeofоператор! @JustAMartin
— Амир Фо

Да, но первоначальный вопрос состоял в том, чтобы отличить любые строковые переменные от числовых переменных. '123` по-прежнему является строкой. Если я передам 123, ответ должен быть, numberно если я передам «123» или «abc» или любой другой заключенный в кавычки литерал, это будет строка, и не имеет значения, может ли она быть разбита на число или нет.
— JustAMartin

@JustAMartin Хорошо, я отредактировал свой ответ.
— Амир Фо

1

Операция XOR может использоваться для определения числа или строки. число ^ 0 всегда будет давать число в качестве вывода, а строка ^ 0 будет давать 0 в качестве вывода.

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

1

Просто и тщательно:

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

Тестовые случаи:

console.log('***TRUE CASES***');
console.log(isNumber(0));
console.log(isNumber(-1));
console.log(isNumber(-500));
console.log(isNumber(15000));
console.log(isNumber(0.35));
console.log(isNumber(-10.35));
console.log(isNumber(2.534e25));
console.log(isNumber('2.534e25'));
console.log(isNumber('52334'));
console.log(isNumber('-234'));
console.log(isNumber(Infinity));
console.log(isNumber(-Infinity));
console.log(isNumber('Infinity'));
console.log(isNumber('-Infinity'));

console.log('***FALSE CASES***');
console.log(isNumber(NaN));
console.log(isNumber({}));
console.log(isNumber([]));
console.log(isNumber(''));
console.log(isNumber('one'));
console.log(isNumber(true));
console.log(isNumber(false));
console.log(isNumber());
console.log(isNumber(undefined));
console.log(isNumber(null));
console.log(isNumber('-234aa'));

0

Просто используйте

myVar.constructor == String

или

myVar.constructor == Number

если вы хотите обрабатывать строки, определенные как объекты или литералы и сохраняемые, вы не хотите использовать вспомогательную функцию.



0

Очень поздно на вечеринку; Тем не менее, следующее всегда работало хорошо для меня, когда я хочу проверить, является ли какой-либо ввод либо строкой, либо числом в одном кадре.

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

0

Создал jsperf для проверки, является ли переменная числом. Довольно интересно! У typeof действительно есть использование производительности. Использование typeofдля чего-либо, кроме чисел, как правило, идет 1/3 скорости какvariable.constructor поскольку большинство типов данных в javascript - это Objects; номера нет!

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

typeof variable === 'number'| самый быстрый | если вы хотите число, например, 5, а не «5»
typeof parseFloat(variable) === 'number' | самый быстрый | если вы хотите число, например, 5 и 5

isNaN()медленнее, но не намного медленнее. Я возлагал большие надежды parseIntи parseFloat, однако, они были ужасно медленными.


0

Для определения чисел важен следующий отрывок из JavaScript: «Хорошие части» Дугласа Крокфорда:

Функция isFinite - лучший способ определить, можно ли использовать значение в качестве числа, поскольку оно отклоняет NaN и Infinity. К сожалению, isFinite попытается преобразовать свой операнд в число, так что это не очень хороший тест, если значение на самом деле не является числом. Вы можете определить свою собственную функцию isNumber:

var isNumber = function isNumber(value) { return typeof value === 'number' &&
            isFinite(value);
};
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.