Перевірте, чи є змінною число чи рядок у 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
Це не правильно! Існує два можливих подання рядка. alar (typeof new String ()) видасть "Object". Гірше, що JavaScript буде періодично перетворюватися між двома представленнями за кадром з метою оптимізації
Джордж Мауер

3
@George Відповідно до ОП, будуть перевірені лише існуючі змінні.
Сампсон

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

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
FYI: 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 Він фактично не викликає метод підрядки, він лише перевіряє, чи є у методу підрядки.
Алокіто

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" ви отримуєте неправильний результат.
Chetan Sastry

1
Я щойно тестував "25", і він повернувся помилково - як би я очікував.
Якоб Геде

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 ["конструктор"] замість 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'. він повертає помилкове.
KChen

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: Better typeof .


Ще є можливість вдосконалення щодо 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 вперше намагається перетворити х у число.
Адріан Варфоломій

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's $.isNumeric()є цікавішим для долара.


isNaN('123')дає хибність, хоча аргумент є числовим рядком, а не числовим типом
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
І це справді повільно.

Тарасабуро, я не знаю, звідки ви отримуєте свої дані, але невеликий орієнтир є в порядку:
Michael Mikowski

Я не вважаю це "дуже повільним". Швидкість тестування перевищує 1 мільйон ітерацій, я вважаю, що це не гірше половини швидкості нативного typeofметоду (0.788s проти 1.481s) у Chrome. Це, безумовно, є прийнятною ефективністю, враховуючи покращені результати. Чому ви вважаєте, що це "насправді повільно?" Можливо, це - в IE6 / 7/8? Але в цих браузерах все "дуже повільно".
Майкл Міковський

Ну, я це сказав, тому що я вже зробив бенчмаркінг. Зберіть нового маленького на jsperf.com/check-typeof-number-again , і на 100 разівtypeof швидше, що мені не вистачає?

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


4

typeof працює дуже добре для мене в більшості випадків. Ви можете спробувати використовувати оператор if

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

де x - будь-яке ім'я змінної на ваш вибір


Що ця відповідь додає до найбільш прихильної?
Bartek Banachewicz

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

Помилка? Просто використовуйте регулярні вирази! :)

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 не є рядком, значення може бути будь-яким.

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 

Якщо ви шукаєте справжній тип, то типofof зробить один.


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

var змінний = '123'; console.log (! isNaN (+ змінна)); дає true, хоча це рядок, а не
числовий

Тому що "123" - це число! Якщо ви хочете знати тип змінної, ви можете легко скористатися typeofоператором! @JustAMartin
Amir Fo

Так, але початкове питання полягало в тому, щоб відрізняти будь-які змінні, набрані рядками, від змінних, введених числом. "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 є Об'єктами; числа немає!

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 та нескінченність. На жаль, isFinite спробує перетворити свій операнд у число, тому це не є хорошим тестом, якщо значення насправді не є числом. Ви можете визначити власну функцію isNumber:

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