JavaScript 判斷變數是否等於 NaN

在 JavaScript 實在有太多奇怪的眉眉角角了,今天因為把字串轉數字用到 parseFloat,如果進去的參數無法轉成數字則會回應 NaN (Not a Number),我就寫了如下語法來判斷:

var score = parseFloat(prompt("Score:"));

if(score === NaN) {
    console.log("Not a Number");
} else {
    console.log(score);
}

這段程式碼乍看之下理所當然,就像 undefined、null 一樣可以直接相等運算,誰知道完全不如預期。

在 JS 裡面很有趣,NaN is Number (Not a Number is a Number),如果今天回傳值是 undefined 的話可以直接相等,因為 undefined 的型態就是 undefined,一般直覺認為 NaN 也是同樣的,型態應該是 NaN,但如果你去檢查會發現,其實 NaN 的型態是 Number,當你進行下面這些運算時,全部都是 False!

NaN == NaN

"NaN" == NaN

"Hi" == NaN

這地雷真的踩很深,其實解法不難,使用 isNaN 函式來判斷即可,例如:

var score = parseFloat(prompt("Score:"));

if(isNaN(score)) {
    console.log("Not a Number");
} else {
    console.log(score);
}

這樣看起來解決問題了,但仔細看下面的幾個運算:

isNaN(NaN) == true

isNaN("hi") == true

isNaN(undefined) == true

isNaN(10) == false

isNaN("10") == false

isNaN 雖然看似解決問題了,但你會發現他並非 NaN === NaN 的判斷,因為 isNaN(“hi”) 回傳是 true,但 “hi” 是個字串,雖然看起來 “hi” is not a number 沒有錯,但嚴格定義來看 “hi” === NaN 應該要是 false,因為 “hi” 是字串,而 NaN 是數字型態! 會發生這種問題是因為當你傳入參數到 isNaN 時,他會先轉換成 Number,也就是 Number(“hi”) === NaN,而 Number(“hi”) 本身會回傳 NaN。

如果你希望「只有 NaN 才是 NaN」嚴格定義版本的 isNaN,可以用 Number.isNaN,參考以下運算:

Number.isNaN(NaN) == true

Number.isNaN("hi") == false

Number.isNaN(undefined) == false

2 thoughts on “JavaScript 判斷變數是否等於 NaN”

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料