深入理解 NaN 與 isNaN 方法

一、NaN

NaN,即 not a number,從字面意思上可以理解為非數(shù)字,但是在 JavaScript 的數(shù)據(jù)類(lèi)型劃分的時(shí)候,我們還是將其劃分進(jìn) number 類(lèi)型:

typeof NaN;    // "number"

實(shí)際上,它是在算術(shù)運(yùn)算過(guò)程中,在原本期望得到一個(gè)數(shù)字類(lèi)型數(shù)據(jù)的地方,卻沒(méi)有辦法得出數(shù)字類(lèi)型的結(jié)果的時(shí)候,其它類(lèi)型編程語(yǔ)言可能將拋出異常,而 JavaScript 將得到一個(gè) NaN:

1 - 'a';        // NaN
1 / 'a';        // NaN
1 - {};         // NaN
1 + NaN;        // NaN
1 * {};         // NaN

但需要注意一些特殊情況:

  • JavaScript 中,+ 既是加法運(yùn)算符,又是字符串連接符(當(dāng)操作數(shù)中含有字符串時(shí),認(rèn)為是字符串連接操作)
1 + 'a';        // '1a'
'1' + 1;        // '11'
  • 當(dāng)分母為 0 的時(shí)候,將得到特殊的 Infinity 和 - Infinity
1 / 0;              // Infinity
1 / (-0);           // -Infinity
  • 操作數(shù)可能被隱式轉(zhuǎn)換
1 + {};    // "1[object Object]"

1 + new Date('2019-09-01'); 
// "1Sun Sep 01 2019 08:00:00 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)"  

1 + [1, 2];    // '11,2'

二 、判斷是否為 NaN
在 JavaScript NaN 有一個(gè)其它類(lèi)型數(shù)據(jù)都不具備的特性,這個(gè)數(shù)據(jù)與它本身不相等:

NaN == NaN;       // false
NaN === NaN;      // false

所以,我們可以基于這一點(diǎn),來(lái)判斷一個(gè)數(shù)據(jù)是否是 NaN:

function ifNaN(data) {
  return data !== data;
}
ifNaN(NaN);        // true
ifNaN(1);          // false

三、原生的 isNaN 方法
第一感覺(jué),isNaN 方法應(yīng)該和我們前面實(shí)現(xiàn)的 ifNaN 效果一樣,但實(shí)際上二者區(qū)別卻很大:

isNaN(null);         // false
isNaN(undefined);    // true
isNaN(1);            // false
isNaN({});           // true
isNaN('123');        // false
isNaN('0xa');        // false

isNaN 的定位跟之前的 ifNaN 不太一樣,ifNaN 是確定一個(gè)數(shù)據(jù)是否是 NaN,是 NaN 就返回 true,否則返回 false;isNaN 是確定一個(gè)數(shù)據(jù)在與其它數(shù)字類(lèi)型數(shù)據(jù)進(jìn)行算術(shù)運(yùn)算之后,是否可能得出 NaN:

null - 1;            // -1
undefined - 1;       // NaN
1 - 1;               // 0
{} - 1;              // NaN
'123' - 1;           // 121
'0xa' - 1;           // 9

這一點(diǎn)上,其實(shí)與上面 isNaN 的行為保持一致了。
在調(diào)用 isNaN 時(shí),如果傳入的參數(shù)不是 number 類(lèi)型,則會(huì)嘗試隱式轉(zhuǎn)換成 number 類(lèi)型的數(shù)據(jù),所以, isNaN(xxx) 其實(shí)與 isNaN(Nunber(xxx)) 等價(jià),所以上面 isNaN 的行為也就解釋得通了。

注:最初版本的 isNaN 是定義在全局對(duì)象 window(瀏覽器環(huán)境) / global(nodejs) 對(duì)象上的,但是 ES6 在 Number 構(gòu)造函數(shù)上添加了一個(gè)靜態(tài)方法 Number.isNaN,其效果與之前的 ifNaN 保持一致了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 全面認(rèn)識(shí)JavaScript的Number對(duì)象 首先一個(gè)是對(duì)JavaScript中Number的理解:JavaSc...
    皮皮坤666閱讀 887評(píng)論 0 0
  • 第一章 前端三大語(yǔ)言:HTML(專(zhuān)門(mén)編寫(xiě)網(wǎng)頁(yè)內(nèi)容)、CSS(編寫(xiě)網(wǎng)頁(yè)樣式)、JS(專(zhuān)門(mén)編寫(xiě)網(wǎng)頁(yè)交互行為) 能簡(jiǎn)寫(xiě)盡...
    fastwe閱讀 1,203評(píng)論 0 0
  • 變量 聲明變量 命名變量區(qū)分大小寫(xiě)的語(yǔ)言第一個(gè)字符是字母或下劃線_,數(shù)字不能作為第一個(gè)字符字符必須是字母,數(shù)字或者...
    flyingtoparis閱讀 897評(píng)論 0 0
  • 標(biāo)簽: 我的筆記 ---學(xué)習(xí)資料:http://javascript.ruanyifeng.com/ 1. 導(dǎo)論 ...
    暗夜的怒吼閱讀 950評(píng)論 0 1
  • JavaScript語(yǔ)言精粹 前言 約定:=> 表示參考相關(guān)文章或書(shū)籍; JS是JavaScript的縮寫(xiě)。 本書(shū)...
    微笑的AK47閱讀 659評(píng)論 0 3

友情鏈接更多精彩內(nèi)容