Проверьте, является ли переменная числом или строкой в ​​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.