JavaScript中最狠的角色:NaN
,为什么说它是最狠的角色呢?因为它狠起来,连自己都不放过!
如果要在纯数学中找到一个变量x,且满足 x != x
,那么很遗憾,数学中不存在这样的变量。但是在JS的世界中却存在这样一个变量,它就是 NaN
,它自己和自己不相等,够不够狠?
1 | NaN == NaN // false |
NaN
的全称是“Not a Number”,它表示一个非数字的值。通常情况下,NaN
出现在以下几种情况:
什么情况会产生NaN?
以下情况都会产生NaN
:
失败的数字类型转换
如果尝试将一个非数字类型的变量转换为数字类型,但转换失败,则会产生NaN
。
1 | Number(undefined); // NaN |
无效的数学运算
在数学运算中,如果运算无法产生一个数字,则会产生NaN
。例如:
1 | Math.sqrt(-1); // NaN,负数的平方根是虚数,不是数字 |
无穷值
当一个数学运算的结果是无穷大或无穷小时,JS会将其转换为NaN
。例如:
1 | 1 / 0; // Infinity |
非数字类型的运算
在JS中,如果对非数字类型的值进行数学运算,通常会产生NaN
。例如:
1 | 'abc' * 2; // NaN,字符串不能参与数学运算 |
其他情况
这个情况和第一种类似,就是将一个非数字类型表示为数字类型时,如果转换失败,也会产生NaN
。例如:
1 | new Date("blabla").getTime(); // NaN,无法将无效的日期字符串转换为时间戳 |
唯一的例外
在JS所支持的所有数学运算中,只有一个运算不会产生NaN
,那就是0次幂运算。
1 | NaN ** 0 // 1 |
如何判断NaN?
给定一个变量x
,如何判断它是否是NaN
呢?由开头的介绍可知,我们无法使用==
或者===
来判断NaN,所以JS提供了专门用于判断NaN的函数:
isNaN(x)
:这个函数主要用来判断x是否能转换为数字,如果不能转换为数字,则返回true
,否则返回false
。注意,这个函数会对非数字类型的值进行隐式转换。Number.isNaN(x)
:这个函数是ES6引入的,它只会判断x
是否是NaN
,不会进行隐式转换。如果x
是NaN
,则返回true
,否则返回false
。Object.is(x, NaN)
:这个函数也是ES6引入的,它可以用来判断x
是否是NaN
。
看几个列子,理解一下。
1 | isNaN(NaN); // true |
面试题
如果让你写一个函数判断一个变量是否是NaN
,你会怎么写?我们可以根据NaN
的特性:NaN与自身不相等来实现这个函数。
1 | function isReallyNaN(x) { |