在JavaScript中检查变量是数字还是字符串

565

有人知道在JavaScript中如何检查一个变量是数字还是字符串吗?


https://dev59.com/3nVD5IYBdhLWcg3wU56H - Mark Schultheiss
34个回答

501

如果你正在处理字面量符号,而不是构造函数,你可以使用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

71
分别表示“字符串”和“数字”。 - Thilo
29
不正确!一个字符串有两种可能的表示方式。alert(typeof new String())会输出“Object”。更糟糕的是,为了优化,JavaScript有时会在幕后来回转换这两种表示方式。 - George Mauer
3
根据原帖,只有现有的变量将被测试。 - Sampson
3
好的,但是假设我有一个函数 isString(str) { return typeof str === 'string' } 一些使用Java的人可能会像这样使用我的方法 var myString = new String("stuff I like"); isString(myString) 这将返回false。另外,我不确定后台转换持续多长时间,我知道当我调用 "hi".length 时,"hi"被转换为一个对象,不确定它何时再次转换回去,或者是否与变量绑定。 - George Mauer
9
没错,但你为什么要使用String对象呢? - Félix Saparelli
显示剩余7条评论

286

最佳做法是使用 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

31
如果您想要计算解析为有效数字的字符串,这似乎是一个不错的解决方案。 - Trevor Burnham
3
FYI:null会被强制转换为0,并且对于 isNumber(null) 返回真。 - Edward
1
function is_number(n) { return /^-?[\d.]+(?:e-?\d+)?$/.test(n);}有什么问题? - OneOfOne
1
这对于像'123abc'这样的字符串也会失败。 - ash
2
@ash 谢谢,我已经更新了解决方案以涵盖这种情况。 - BitOfUniverse
显示剩余10条评论

77

我发现最好的方法是检查字符串上的方法,例如:

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 更好,因为它可以始终测试字符串,无论是原始字符串还是字符串对象。你只需要测试所需类型的唯一方法即可。 - ADTC
从代码维护者的角度来看,选择这条路可能会令人困惑。“为什么他们使用了substring而没有传递任何值?我错过了什么业务逻辑?”至少,这需要与解释所涉及逻辑的注释配对。 - Lemmings19
4
它实际上并没有调用substring方法,它只是检查x是否有一个substring方法。 - Alokito
2
我喜欢这种鸭子类型的思想,但是这对于像{substring:"hello"}这样的东西会失效。我知道为了我的目的,我只需测试我需要执行的具体操作(模数)在我需要检查的类型上所做的操作(对于字符串模数返回未定义),然后检查它而不是获取它的类型。 - Tadhg McDonald-Jensen

52

从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

2
这在Internet Explorer上没有支持。 - davedeecoder
6
无法在字符串上使用,这是原始问题。 - Eric Grange
那是一个很好、简单的答案! - Konrad G
1
这提供了部分答案,但是它是非常好的部分答案 - 三角形向上。 - Kamil Kiełczewski
@EricGrange,字符串不是数字。 - João Pimentel Ferreira
喜欢这种方法。没有点赞是因为它并没有真正回答原始问题,但确实是一个很好的发现! - Arnaldo Capo

47
您正在寻找的是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"));

请查看 MDN 上的 JavaScript isNaN() 函数


3
他们选择使用反向操作作为方法名称,我觉得很奇怪。叫做isNumber()似乎更符合直觉。 - Nathan Taylor
12
实际上,'isNumber'并不是'isNaN'的逆操作。在JavaScript中,NaN是一种特殊的数字值。'isNaN'将所有提供的参数转换为数字,并检查结果是否为NaN。对于像"25"这样的字符串,它会得到错误的结果。 - Chetan S
3
我刚刚用“25”进行了测试,结果返回了false - 这正是我所期望的。 - Jakob Gade
2
NaN是IEEE 754二进制浮点算术标准中的一个特殊值,而不仅仅是JavaScript的东西。(嗯,准确地说:“IEEE标准的9007199254740990(即(2^53)-2)个不同的“非数字”值在ECMAScript中表示为单个特殊的NaN值。”) - NickFitz
6
请记住,isNaN 对于 null 返回 false(但对于 undefined 返回 true)。 - Toni
显示剩余5条评论

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) 看起来已经足够了,即使是字符串字面量。 - Chris Noe
2
如果 o === null,这将导致一个异常。 - T. Junghans
3
我喜欢这个解决方案。为了避免空值异常,可以使用 o["constructor"] 而不是 o.constructor。 - dreamerkumar
2
@VishalKumar 所以这就是所有人需要的吗:function is (type, value) { return value["constructor"] === type; } - ceving

17

试试这个:

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

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

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

尝试使用“-2”。它会返回false。 - KChen
2
为什么你保留(或不编辑)一个不起作用的答案?请注意,负数也可以是整数。 - Asons

15

简单而彻底:

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

这个答案有所帮助,尽管它并没有真正回答原始问题 :) - Roey
1
等等,这不对吗?`const myVar = "5"; // 将其设置为字符串。isNumber(myVar); // 是的,但它应该是false,因为这个变量是一个字符串而不是一个数字。` - Don P
1
@DonP 是的,正如你和Roey指出的那样,我的回答并没有回答原问题。我在这里发布它是因为它似乎是一个有用的发现,而且比这里的许多答案更短/更好,这些答案实际上是关注于确定一个值是否[已经是一个常规数字或者是可以转换成一个数字的字符串]。 - MarredCheese

14

最佳执行方法:

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

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

2012年5月12日更新: 完整示例请参见Javascript: A Better typeof


关于 realTypeOf,仍有改进的空间:realTypeOf(NaN) -> "Number",这与 typeof 的行为相同,但仍远非理想。 - Max

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接