如果数值运算的操作数不是数字类型(或者无法解析为常规的十六进制或十进制数字),就无法返回一个有效的数字,这种情况下返回值为 NaN
NaN 是一个 “警戒值”(sentinel value, 有特殊通途的常规值),用于指出数字类型中的错误情况,即“执行数字运算没有成功,这是失败后返回的返回”
let a = 2 / 'foo' // NaN
a == NaN // false
a === NaN // false
NaN 是一个特殊值,它和自身不相等,是唯一一个非自反(自反,reflexive,即 x === x 不成立)的值。而 NaN != NaN 为 true。
JavaScript 内部提供了 isNaN 来让我们判断它。
let a = 2 / 'foo'
isNaN(a) // true
然而操起起来并没有那么容易,isNaN(...) 有一个严重的缺陷,它的检查方式过于死板,就是“检查参数是否不是NaN,也不是数字”。这样做的结果并不太准确:
let a = 2 / 'foo'
let b = 'foo'
a // NaN
b // 'foo'
window.isNaN(a) //true
window.isNaN(b) // true
这个 bug 自 JavaScript 问世以来就一直存在,至今已超过19年。
从 ES6 开始我们可以使用工具函数 Number.isNaN(...)
ES6 之前的浏览器的 polyfill:
if (!Number.isNaN) {
Number.isNaN = function(n) {
return {
typeof n === 'number' && window.isNaN(n)
}
}
}
实际上还有一个更简单3的方法来判断NaN,即利用 NaN 不等于自身的这个特点。NaN 是 JavaScript 中唯一一个不等于自身的值。
if (!Number.isNaN) {
Number.isNaN = function(n) {
return n !== n
}
}