本文属于《Javascript基础纪要》系列文章.
在JS中,在判断一个变量是否是数字时,最快的方法是:
1 | typeof v === 'number' |
如果是如此简单,那么本文就没有存在的必要了.这里的坑在于,通过new Number(1)这样创造的数字,用typeof判断时会得到object而不是number(虽然几乎没人会用这种蛋疼的方法来创建数字…).
如果真是用new Number()创造的数字,要怎么判断?
1 | toString.call(obj) == '[object Number]' |
这就有点长了,而且效率下降了很多(但为了能判断出来也是情非得已).有的人还不是直接用的toString,还是用的Object.prototype.toString,就更长了,不过没有必要.
这样一来,两种数字我们都可以判断出来了,但还有种情况,就是变量本来就不是数字,那我们也要尽快得出false,少走弯路.
通过前面的代码我们知道,如果一个变量真的是数字,那么typeof返回的只可能是number或object,如果连object都不是,就可以得出变量不可能是数字的结论.
于是完整代码如下:
1 2 3 4 5 | function isNumberFaster(obj) { if (typeof obj == 'number') return true; if (typeof obj != 'object') return false; return Object.prototype.toString.call(obj) == '[object Number]' } |
这是国外的前辈写的,简单易懂,你也可以自己减少一些代码量.点这里还有效率对比
2015-5-5更新:
经过网友破釜沉舟的评论的提醒,我发现了更简单的方法:
1 2 3 4 5 | function isNum (n) { return ('number' === typeof n) ? true : 'object' === typeof n ? n*1 == n : false; } |
这个函数的原理在于: 先直接判断typeof是number则返回true,否则判断type是不是object,是的话就判断n*1==n。n*1能强制转换成number,不过如果不是数字,转换后也只会得到NaN了,所以不会等于他自身了。
这里要插一句:任意两个NaN都是互不相等的!!
不过’1.23’*1==’1.23’,这样却是正确的,所以我们必须在typeof n === ‘object’的情况下来强制转换类型。
最后,这两种都不是则表示参数真的不是数字了。
不过,这个函数还是有bug的,因为有一种字符串,是这样的: new String(1),这样产生的字符串,type也是object,转成数字后也能等于自身。这样的情况,该如何判断呢?
方法当然是有的,不过这样一来这个函数就会变得比上个函数还长,有点得不偿失啊。。。。所以我还是希望大家都不要用new Number和new String来声明数字和字符串,蛋疼。