javascript - 為什麼在 JS 中 isNaN(null) == false?
這段 JS 代碼彈出一個提示說「我認為 null 是一個數字」,這讓我覺得有點困惑。我漏掉了什麼嗎?
if (isNaN(null)) {
alert("null is not a number");
} else {
alert("i think null is a number");
}我正在使用 Firefox 3。那是瀏覽器的錯誤嗎?
其他測試:
console.log(null == NaN); // false
console.log(isNaN("text")); // true
console.log(NaN == "text"); // false所以,問題似乎不是與 NaN 的精確比較?
編輯:現在問題已經得到回答,我已經整理了我的帖子,以便存檔有更好的版本。然而,這使得一些評論甚至一些答案變得有點難以理解。不要責怪他們的作者。我更改的內容包括:
- 刪除了說我最初搞砸了標題、顛倒其意思的備註
- 先前的回答顯示我沒有足夠清楚地說明為什麼我覺得這種行為很奇怪,所以我添加了檢查字串並進行手動比較的例子。
答案#1
我認為這段代碼試圖詢問「x 是否為數字?」這裡的特定情況是 x=null。函數 isNaN() 可用來回答這個問題,但從語義上而言,它是專指 NaN 值。以下是維基百科對 NaN 的說明:
NaN(不是一個數字)是一種數值資料類型的值,表示未定義或不可表示的值,特別是在浮點運算中。
在大多數情況下,我們認為「null 是數值嗎?」的答案應該是否定的。然而,isNaN(null) == false 在語義上是正確的,因為 null 不是 NaN。
這裡是算法解釋:
函數 isNaN(x) 嘗試將傳入的參數轉換為數字1(等同於 Number(x)),然後測試該值是否為 NaN。如果參數無法轉換為數字,Number(x) 將返回 NaN2。因此,如果參數 x 轉換為數字的結果是 NaN,則返回 true;否則返回 false。
所以在特定情況下 x=null,null 會被轉換為數字 0(試著評估 Number(null),你會看到它返回 0),而 isNaN(0) 返回 false。只包含數字的字串可以被轉換為數字,並且 isNaN 也返回 false。無法轉換為數字的字串(例如 'abcd')會導致 isNaN('abcd') 返回 true,特別是因為 Number('abcd') 返回 NaN。
除了這些明顯的邊界情況外,還有返回 NaN 的標準數值原因,例如 0/0。
至於題目中看似不一致的相等測試,NaN 的行為是被明確規定的,任何比較 x == NaN 都會返回 false,無論另一個運算元是什麼,包括 NaN 本身1。
答案#2
我剛好自己也遇到這個問題。
對我來說,使用 isNaN 的最佳方式如下
isNaN(parseInt(myInt))以上面 phyzome 的例子為例,
var x = [undefined, NaN, 'blah', 0/0, null, 0, '0', 1, 1/0, -1/0, Number(5)]
x.map( function(n){ return isNaN(parseInt(n))})
[true, true, true, true, true, false, false, false, true, true, false]
( 我根據輸入對齊了結果,希望這能讓閱讀更容易。 )
這對我來說似乎更好。
答案#3
(我另一則評論採取實際的方法。這裡是理論方面。)
我查閱了 ECMA 262 標準,這就是 JavaScript 實作的標準。他們對 isNaN 的規範如下:
將 ToNumber 應用於其參數,如果結果是 NaN 則返回 true,否則返回 false。
第 9.3 節規定了 ToNumber 的行為(它不是可調用的函數,而是類型轉換系統的一個組件)。總結表格,某些輸入類型會產生 NaN。這些類型包括 undefined 類型、number 類型(但僅限值為 NaN)、任何原始表示為 NaN 的物件,以及任何無法解析的 string。這留下了 undefined、NaN、new Number(NaN),以及大多數字串。
任何輸入在傳遞給 ToNumber 後產生 NaN 作為輸出時,傳遞給 isNaN 會產生 true。由於 null 能夠成功轉換為數字,它不會產生 true。
這就是為什麼。
答案#4
這的確令人不安。這裡是我測試過的一組數值:
var x = [undefined, NaN, 'blah', 0/0, null, 0, '0', 1, 1/0, -1/0, Number(5)]
它在 Firebug 控制台中的評估結果為:
,NaN,blah,NaN,,0,0,1,Infinity,-Infinity,5
當我呼叫 x.map(isNaN)(對每個值呼叫 isNaN)時,我得到:
true,true,true,true,false,false,false,false,false,false,false
總之,isNaN 看起來非常沒用!(編輯:除了事實上 isNaN 只在 Number 上 定義,在這種情況下它運作得很好——只是名稱有點誤導。)
順便提一下,這些值的類型如下:
x.map(function(n){return typeof n})
-> undefined,number,string,number,object,number,string,number,number,number,number
