JS判断元素为数字的奇异写法分享

作者:异步漫步时间:2026-10-27 05:45:46浏览:211

本文介绍了一种在underscore源码中发现的JavaScript判断数字类型的奇异写法:利用a===+a。通过对比typeof和Object.prototype.toString,分析该写法在性能上的优势,即避免了字符串遍历比较,适用于需要高效判断数值类型的场景。

underscore源码中的数字判断逻辑

本文源自阅读underscore(1.3.3)库源码时的发现,主要关注其each方法的实现细节。


相关代码如下:

 
var each = _.each = _.forEach = function(obj, iterator, context) {
if (obj == null) return;
if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context);
} else if (obj.length === +obj.length) {
for (var i = 0, l = obj.length; i < l; i++) {
if (iterator.call(context, obj[i], i, obj) === breaker) return;
} 
} else {
for (var key in obj) {
if (_.has(obj, key)) {
if (iterator.call(context, obj[key], key, obj) === breaker) return;
} 
} 
} 
}; 

奇异写法a===+a的原理与等价转换

在该方法中,存在一句关键的判断逻辑。


具体代码片段如下:

if (obj.length === +obj.length)

起初难以理解,后经专业人士解析,此句逻辑等价于以下判断:


等价代码如下:

if (typeof obj.length === 'number')

这实际上用于判断obj.length是否为数字类型。通常我们使用typeof或Object.prototype.toString进行类型检查,但这种利用一元加号转换的写法较为罕见,不易被常规开发者理解。



类型判断方法的对比与性能分析

许多前端库提供了类型判断的工具函数,例如:


代码示例如下:

 
function isNumber1(a){
return typeof a === 'number'
} 

另一种常见做法是使用Object.prototype.toString。


相关代码如下:

 
function isNumber2(a) {
return Object.prototype.toString.call(a) === '[object Number]'
} 

若将其改写为上述奇异写法,则表现为:


代码示例如下:

 
function isNumber3(a){
return a === +a
} 

使用多种数据类型进行测试。


测试代码如下:

 
var arr = ['1', true, false, undefined, null, {}, [], 1]
for (var i=0; i<arr.length; i++) {
console.log(isNumber3(arr[i]))
} 

测试结果仅数组最后一项返回true,即只有数字类型满足 a === +a 为真。


之所以不首选typeof,是因为字符串比较理论上需要遍历所有字符,性能与字符串长度成正比,而数值比较效率更高。

作者最新文章