美文网首页
浅谈 JS 中 isNaN() 与 Number.isNaN()

浅谈 JS 中 isNaN() 与 Number.isNaN()

作者: 中國式情調 | 来源:发表于2020-08-12 20:59 被阅读0次

    1 关于 NaN

    当算术运算符返回一个未定义或其无法表示的值(除 Infinity 与 - Infinity),或不能将非数值类型强制转换为数值时,就会产生 NaN,表示不是一个有效数字,not a number。

    NaN 是一个全局对象属性,初始值是 NaN,和 Number.NaN 相同。是 number 类型。

    与 JavaScript 中其他值不同的是, 不能通过相等操作符( == 和 === )等来判断数据是否是 NaN,因为 NaN 不与任何值相等,包括其自身。

    NaN === NaN         // false
    Number.NaN === NaN  // false
    1 === NaN           // false
    '1' === NaN         // false
    

    2 isNaN() 的必要性

    由于 NaN 通过 ==!==== 、以及 !== 与其他任何值及其他 NaN 值比较都不相等。故需使用 isNaN() 来判断值是否是 NaN。

    一个 isNaN 的 polyfill 理解:

    const isNaN = value => {
        const x = Number(value)
        return x !== x
    }
    

    isNaN 方法通过 Number() 隐式的将值进行转换后进行比较。

    isNaN(NaN)        // true
    isNaN(undefined)  // true Number(undefined) NaN
    isNaN({})         // true Number({}) NaN
    isNaN('s')         // true Number('s') NaN
    
    isNaN([])         // false Number([]) === 0
    isNaN(1)          // false
    isNaN(new Date()) // false Number(new Date()) 1597233148879
    
    isNaN('')         // false Number('') === 0
    isNaN(false)      // false Number(false) === 0
    isNaN(null)       // false Number(null) === 0
    

    3 isNaN() 的缺陷

    如果 isNaN 函数的参数不是 Number 类型, isNaN 函数会首先尝试将这个参数通过 Number() 强制转换为数值,然后才会对转换后的结果进行判断。对于 undefined、{} 、非数字字符串等值,在强制类型转换失败,得到 NaN 后判断为 true。但其实其并不是特殊值 NaN。

    实际上, isNaN() 得到的结果是被测值在被强制转换为数值后,是否不是一个数。并没有完全达到判断是否是 NaN 这一特殊值的目的。

    单纯使用 x !== x 来判断 NaN 比 isNaN() 更加可靠。

    4 isNaN() 的特殊行为

    isNaN() 并非一无是处,由于 isNaN() 基于 Number() 的强制类型转换,所以:

    • 如果 isNaN(value) 返回的是 false,那么 value 在任何算数表达式中都不会使表达式等于 NaN
    • 如果返回 truevalue 会使所有算数表达式返回 NaN

    可以利用这一特殊行为来检测函数参数的可运算性(可以下像 number 一样进行加减乘除等运算)。如果不可运算,则可赋予这个参数一个默认的值或其他合适的内容。这样,就可以得到一个隐式转换参数值的函数。

    5 Number.isNaN() 的改进

    3 isNaN() 的缺陷 中所述,Number 提供了一种更稳妥的方法判断数据是否是 NaN

    一个 Number.isNaN 的 polyfill 理解:

    Number.isNaN = value => {
        return typeof value === 'number' && isNaN(value)
    }
    

    可以看出 polyfill 理解中 加入了 number 类型判断。

    实际中 Number.isNaN() 不会自行将参数转换成数字。

    Number.isNaN(NaN);        // true
    Number.isNaN(Number.NaN)  // true
    Number.isNaN(0 / 0)       // true
    
    Number.isNaN(undefined)   // false
    Number.isNaN({})          // false
    Number.isNaN('s')         // false
    

    Number.isNaN() 只有在参数是值为 NaN 的数字时,才会返回 true

    Number.isNaN() 判断的是被测值是否是 NaN 这一特殊值。

    6 参考资料

    [1] [MDN] NaN

    [2] [MDN] Number.NaN()

    [3] [MDN] isNaN

    [4] [MDN] Number.isNaN()

    相关文章

      网友评论

          本文标题:浅谈 JS 中 isNaN() 与 Number.isNaN()

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