美文网首页
[前端日记]1.x.1/解读NaN

[前端日记]1.x.1/解读NaN

作者: 猪脚面线 | 来源:发表于2018-02-20 19:57 被阅读8次

    Javascript中有一个特殊的对象:NaN,它是「not a number」的缩写。总结了以下几点需要注意,如有错误,烦请指正:P

    1. Javascript中返回NaN的情况


    就目前所学来看,以下两种情况会返回NaN:

    • 表达式计算
      一个表达式中如果有减号 (-)、乘号 (*) 或 除号 (/) 等运算符时,JS 引擎在计算之前,会试图将表达式的每个分项转化为Number 类型(使用 Number()做转换)。如果转换失败,表达式将返回 NaN 。
      一句话理解:任何数除以、减、乘非数值(undefined、string、object)时,都会直接返回NaN
    100 - '2a' ; // NaN 
    '100' / '20a'; // NaN 
    '20a' * 5 ; // NaN
    undefined / 5; // NaN
    undefined * "hello" // NaN
    
    • 类型转换失败
      使用 parseIntparseFloatNumber 将一个非数字的值转化为数字时,表达式返回 NaN
    "abc" - 3   // NaN
    parseInt("abc")  // NaN
    parseFloat("abc") //NaN
    Number("abc")    //NaN
    

    NaN带来的坑


    陷阱1:typeof NaN // 返回number

    这种情况下返回了number。
    在JS中,整数和浮点数都统称为Number,除此之外,还有一个特殊的数值类型就是NaN。他不是一个数字,而是一种数值类型,这也解释了typeof NaN // 返回number

    陷阱2:NaN == NaN // 返回false

    无论相等还是全等,NaN与自身比较都返回false
    因为NaN表示一个无法表示的值,而有很多方法来表示一个非数字,所以一个非数字不会等于另一个为NaN的非数字。比如0/0返回NaN,0/'fail'也返回NaN,而0/0 != 0/’fail’,所以NaN == NaN返回false。

    陷阱3:判断一个值是否为NaN

    如上,==,===均不能用来判断一个值是否是NaN。必须使用Number.isNaN()isNaN函数来检验,下面我们来看下他们的用法。

    isNaN()


    通常我们用isNaN来判断一个值是否是NaN,如下

    isNaN(NaN) // true
    isNaN(undefined) // true
    isNaN({}) // true
    
    isNaN(true) // false,为1
    isNaN(null) // false,为0
    isNaN("") // false ,为0
    isNaN(" ") // false,带空格的字符串转换为数字为0
    isNaN([]) // false,空数组转换为数字为0
    

    isNaN()接收一个参数,参数可以为任意数据类型。如果接收的参数是数字类型,返回false;如果是其他类型(除了数字的任何其他类型),则返回true;

    1. 若接收的参数为数字类型,返回false,表示不是NaN
    2. 若参数为非数字类型,会通过toNumber()将值强制转换为数值,再进行判断。
    3. 如接受的参数是空,比如[](空数组)、“”(空字符串)、null等,会在过程中转换为数字类型的0,从而返回false。

    如下代码,在调用isNaN()时,遇到字符串会强制进行隐式转换。

    isNaN("1");            // false "1" 被转化为数字 1,因此返回false
    isNaN("Hello World"); // true "Hello World" 被隐式转化成数字`NaN`
    

    总结一下isNaN()的坑:
    如果传入的参数不是number类型,isNaN()会尝试将参数转换为数值,然后再对转换后的数值进行判断。因此,就算对于能够被转换为数值的数据类型来说(要特别注意,空字符串、布尔、null、空数组会返回0,布尔值会返回对应数值),返回false值也是反直觉的。

    说到底,其实是Javascript强制类型转换的坑啊!

    ES6新特性 Number.isNaN()


    例如,空字符串就明显不是数值,但是还是返回了0,这是相当的反直觉的!

    所以,我们能否不进行隐式转换来判断NaN呢?答案是,可以的!

    ES6引入了另一种判断方法来填坑——Number.isNaN(x)。通过这个函数来检测x是否是一个非数值,这方法比isNaN()更为可靠。只有在参数是真正的数值类型,且判断后值为 NaN 的时候才会返回 true。

    Number.isNaN(NaN)  // true,NaN既是数值类型,返回的又是NaN
    Number.isNaN("NaN") // false,这里"NaN"是string,不是数字类型,所以直接返回false
    
    Number.isNaN("hello") // false
    isNaN("hello") // true,Number("hello")返回NaN,再判断isNaN(NaN) // true
    
    Number.isNaN({}) // false
    isNaN({}) // true,Number({})返回NaN,判断同上
    
    Number.isNaN("") // false
    isNaN("") // true
    

    总的来说,Number.isNaN()进行了更严格的判断。

    相关文章

      网友评论

          本文标题:[前端日记]1.x.1/解读NaN

          本文链接:https://www.haomeiwen.com/subject/gvegtftx.html