专栏首页JetpropelledSnake前端学习之JavaScript中的 NaN 与 isNaN

前端学习之JavaScript中的 NaN 与 isNaN

NaN

NaN 即 Not a Number ,不是一个数字。 在 JavaScript 中,整数和浮点数都统称为 Number 类型 。除此之外,Number 类型还有一个很特殊的值,即 NaN 。它是 Number 对象上的一个静态属性,可以通过 Number.NaN 来访问 。 

console.log(Number.NaN); // NaN

在 ECMAScript v1 和其后的版本中,还可以用预定义的全局属性 NaN 代替 Number.NaN 。

console.log(NaN); // NaN

在以下两种场景中,可能会产生 NaN 值 。

【1】表达式计算

一个表达式中如果有减号 (-)、乘号 (*) 或 除号 (/) 等运算符时,JS 引擎在计算之前,会试图将表达式的每个分项转化为 Number 类型(使用 Number(x) 做转换)。如果转换失败,表达式将返回 NaN 。

100 - '2a' ; // NaN
'100' / '20a'; // NaN
'20a' * 5 ; // NaN
undefined - 1; // NaN, Number(undefined) == NaN
[] * 20 ; // 0, Number([]) == 0
null - 5; // -5, Number(null) == 0

而 加号 (+) 不会将其两边的变量转化为 Number 类型,这是因为JS表达式的执行顺序是按照运算符的优先级从左到右依次进行的,如果加号 (+) 两边的变量都是 Number 类型时,才会做数字相加运算,如果其中有一个变量是字符串,则会将两边都作为字符串相加。

5 + 4 + '6' = '96';
1 + '2' + 3 =  '123'

【2】类型转换

直接使用 parseInt,parseFloat 或 Number 将一个非数字的值转化为数字时,表达式返回 NaN 。

'abc' - 3   // NaN
parseInt('abc')  // NaN
parseFloat('abc') // NaN
Number('abc')    // NaN

对于 数字+字符 的值,其转化结果会有所不同:

Number('123abc'); // NaN
parseInt('123abc'); // 123
parseInt('123abc45'); // 123
parseFloat('123.45abc');// 123.45

Number 转换的是整个值,而不是部分值;parseInt 和 parseFloat 只转化第一个无效字符之前的字符串。 另外,一元加操作符也可以实现与 Number 相同的作用。 

+ '12abc'; // NaN
+ '123'; // 123
+ '123.78'; // 123.78
+ 'abc'; // NaN

因此,当一个字符串不能被 Number、parseInt 或 parseFloat 成功转换时,就返回 NaN,表示该字符串无法被识别为数字类型,这是一个异常状态,并不是一个确切的值。 

isNaN

isNaN() 是一个全局方法,它的作用是检查一个值是否能被 Number() 成功转换 。 如果能转换成功,就返回 false,否则返回 true 。

isNaN(NaN)    // true 不能转换
isNaN('123')   // false 能转换
isNaN('abc')    // true 不能转换
isNaN('123ab')   // true 不能转换
isNaN('123.45abc') // true 不能转换

可以看出,isNaN() 没有办法判断某个值本身是否为 NaN 。如果想要知道某个值本身是否为 NaN,可以利用 NaN 不等于自身 这一特性来判断。

function selfIsNaN(value){
    return value !== value
}

另外,ES6 在 Number 对象上也提供了 isNaN()  方法,和全局方法 isNaN() 不同的是,它用于判断某个值本身是否为 NaN,而不需要进行类型转换。

Number.isNaN('123'); // false 本身不是NaN
Number.isNaN('abc'); // false 本身不是NaN
Number.isNaN(NaN); // true 本身是NaN

原创发布 @一像素  2016 博客园 

【参考资料】

[1] 详解 ECMAScript 数据类型

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 前端学习之NaN浅析

      在学习Java集合的时候遇到了Float.isNaN(float)函数,点进去一看就不理解了,函数实现如下:

    Jetpropelledsnake21
  • Prometheus监控学习笔记之初识PromQL

    Prometheus 提供了一种功能表达式语言 PromQL,允许用户实时选择和汇聚时间序列数据。表达式的结果可以在浏览器中显示为图形,也可以显示为表格数据,或...

    Jetpropelledsnake21
  • 深度学习笔记之为什么是SoftMax

     首先后面一层作为预测分类的输出节点,每一个节点就代表一个分类,如图所示,那么这7个节点就代表着7个分类的模型,任何一个节点的激励函数都是:

    Jetpropelledsnake21
  • 手把手教你测微信小程序

    ? WeTest 导读 在小程序持续大量爆发的形势下,现在已经成为了各平台竞争的战略布局重点。至今年2月,月活超500万的微信小程序已经达到237个,其中个人...

    WeTest质量开放平台团队
  • GBDT+LR算法解析及Python实现

    参考:https://www.cnblogs.com/wkang/p/9657032.html

    用户2769421
  • GBDT+LR算法解析及Python实现

    本质上 GBDT+LR 是一种具有 stacking 思想的二分类器模型,所以可以用来解决二分类问题。这个方法出自于 Facebook 2014 年的论文 Pr...

    统计学家
  • 新手村:Redis进阶篇一

    Redis HyperLogLog 是用来做基数统计的算法,每个 HyperLoglog 键只需要占用 12KB 内存,就可以计算接近 264 个不同的基数。H...

    syy
  • Linux下常用的shell脚本整理

    <转>分享下看到比较好的关于常用的shell脚本,供大家学习: 1、脚本之间互相调用与传递参数   "1.sh"的脚本,接受参数。如下,如果有一个...

    吴柯
  • FPGA计算3行同列数据之和

    实验:FPGA计算3行同列数据之和 实验要求:PC机通过串口发送3行数据(一行有56个数据,3行共有56*3=168个数据)给FPGA,FPGA计算3行同一列数...

    NingHeChuan
  • python数据库-MongoDB的安装(53)

      NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL"。

    Se7eN_HOU

扫码关注云+社区

领取腾讯云代金券