Appleex
Appleex
Published on 2025-02-09 / 18 Visits
0
0

前端 | Javascript 中 NaN、isNaN 与 Number.isNaN 的区别

Javascript 中 NaN、isNaN 与 Number.isNaN 的区别

前言

在 JavaScript 的数字类型 Number 中,我们最常使用的大概是整数类型与浮点数类型,但除这两者外,还有个特殊的存在 NaN,为什么 NaN !== NaN ?我们如何判断一个值是否等于 NaN 呢?

介绍

NaN 全称是 Not-A-Number (不是一个数字),我们可以通过 Number.NaN 来获得一个 NaN

在类型转换失败时,我们常常会得到一个 NaN,需要注意的是,NaN 是 JS 中唯一一个自身不相等的存在

Number.NaN  // NaN
NaN === NaN // false

具体内容

为什么 NaN !== NaN

NaN 只是 Number 上的一个静态属性。

Number('echo') // NaN

比如 Number('echo') 会得到 NaN,它只是为了告诉你这个值不是一个数字,一种表示方法,而非一个精准有效的值,因此 NaN 不能参与计算,也无法与自身比较。

什么情况下产生 NaN

当 Number 提供的类型转换方法在解析一个值却无法返回数字时:

Number('echo') // NaN

parseInt('echo123') // NaN
parseInt('123echo') // 123

parseFloat('测试文本123.1') // NaN
parseFloat('123.1测试文本') // 123.1

计算中使用 [-/] 运算符,参与计算的值转换类型失败时:

1 - '听风是风' // NaN
1 * '123时间跳跃' // NaN
1 / 'echo123' // NaN

特别注意,两个数字 0 相除也会得到 NaN

0 / 0 // NaN

isNaN 方法能否判断一个值严格等于 NaN

window 上有一个全局方法 isNaN(),可能大分部人习惯理解此方法为判断一个值是等于 NaN,这是因为 isNaN 直译就是 “是不是 NaN” 所带来的误解,其实本意不是这样:

isNaN(123) // false
isNaN('123测试文本') // true
isNaN(NaN) // true

当我们向 isNaN 传递一个参数,它的本意是通过 Number() 方法尝试转换参数的类型为 Number,如果转换成功返回 false,否则转返回 true它只是判断这个参数能否转成数字而已,并不是判断是否严格等于 NaN

所以当你要判断某个值是否严格等于 NaN 时无法使用 isNaN() 方法,毕竟你传递任意字符串它都会返回 true。

ES6 中提供了一个 Number.isNaN() 方法用于判断一个值是否严格等于 NaN

Number.isNaN(NaN) // true

isNaN 最大的区别是,Number.isNaN 不存在转换类型的行为,这点是最大的不同:

isNaN(NaN) // true
Number.isNaN(NaN) // true

isNaN('听风是风') // true
Number.isNaN('听风是风') // false

我们在前面说过,NaN 是唯一一个与自身不相等的特殊值,如果你觉得 Number.isNaN 存在兼容问题,也可以利用这个特点自己定义验证方法:

const ISNAN = (value) => value !== value;
ISNAN('听风是风'); // false
ISNAN(123); // false
ISNAN(NaN); // true

如何判断两个 NaN 相等

在 ES5 中提供了 Object.is() 方法,用于判断两个值是否属于同一个值,而此方法可用于 NaN 是否相等的判断,比如

Object.is(NaN, NaN); // true

Object.is() 接受两个参数,此 API 详情可见 MDN 也就是用于做比较的两个参数,这里做个简单补充。

参考文献


Comment