此頁面由社群從英文翻譯而來。了解更多並加入 MDN Web Docs 社群。
NaN
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2015年7月.
NaN 全域屬性是一個表示非數值的值。
In this article
嘗試一下
function sanitize(x) { if (isNaN(x)) { return NaN; } return x;}console.log(sanitize("1"));// 預期輸出:"1"console.log(sanitize("NotANumber"));// 預期輸出:NaN值
與Number.NaN 相同的數值。
NaN 的屬性特性 | |
|---|---|
| 可寫 | 否 |
| 可列舉 | 否 |
| 可配置 | 否 |
描述
NaN 是全域物件的一個屬性。換句話說,它是全域作用域中的一個變數。
在現代瀏覽器中,NaN 是一個不可配置、不可寫入的屬性。即使在非現代瀏覽器中,也應避免覆寫它。
有五種不同類型的運算會回傳NaN:
- 數值轉換失敗(例如:顯式的
parseInt("blabla")、Number(undefined),或隱式的Math.abs(undefined)) - 結果不是實數的數學運算(例如:
Math.sqrt(-1)) - 不定型(例如:
0 * Infinity、1 ** Infinity、Infinity / Infinity、Infinity - Infinity) - 運算元為
NaN或被強制轉型為NaN的方法或表達式(例如:7 ** NaN、7 * "blabla")——這意味著NaN具有傳染性 - 其他將無效值表示為數值的情況(例如:無效的Date
new Date("blabla").getTime()、"".charCodeAt(1))
NaN 及其行為並非 JavaScript 所首創。它在浮點數運算中的語義(包括NaN !== NaN)是由IEEE 754 標準所定義。NaN 的行為包括:
- 如果
NaN涉及數學運算(但不包括位元運算),結果通常也是NaN。(參見下方的反例。) - 當
NaN是任何關係比較(>、<、>=、<=)的運算元之一時,結果總是false。 NaN與任何其他值比較(透過==、!=、===和!==)結果皆不相等——包括與另一個NaN值比較。
NaN 也是 JavaScript 中的falsy 值之一。
範例
>測試是否為 NaN
要判斷一個值是否為NaN,使用Number.isNaN() 或isNaN() 是最清楚的方法——或者,由於NaN 是唯一不等於自身的值,你可以執行自我比較,如x !== x。
NaN === NaN; // falseNumber.NaN === NaN; // falseisNaN(NaN); // trueisNaN(Number.NaN); // trueNumber.isNaN(NaN); // truefunction valueIsNaN(v) { return v !== v;}valueIsNaN(1); // falsevalueIsNaN(NaN); // truevalueIsNaN(Number.NaN); // true然而,請注意isNaN() 和Number.isNaN() 之間的差異:前者如果值目前是NaN,或者在強制轉型為數值後會變成NaN,就會回傳true;而後者只有在值目前就是NaN 時才會回傳true:
isNaN("hello world"); // trueNumber.isNaN("hello world"); // false基於同樣的原因,使用 BigInt 值時,isNaN() 會拋出錯誤,而Number.isNaN() 則不會:
isNaN(1n); // TypeError: Conversion from 'BigInt' to 'number' is not allowed.Number.isNaN(1n); // false此外,某些陣列方法無法找到NaN,而其他方法則可以。具體來說,尋找索引的方法(indexOf()、lastIndexOf())無法找到NaN,而尋找值的方法(includes())則可以:
const arr = [2, 4, NaN, 12];arr.indexOf(NaN); // -1arr.includes(NaN); // true// 接受適當定義謂詞的方法總是可以找到 NaNarr.findIndex((n) => Number.isNaN(n)); // 2關於NaN 及其比較的更多資訊,請參見相等性比較與相同性。
可觀察到的不同 NaN 值
產生兩個二進位表示法不同但都是NaN 的浮點數是可能的,因為在IEEE 754 編碼中,任何指數為0x7ff 且尾數非零的浮點數都是NaN。在 JavaScript 中,你可以使用型別陣列進行位元級的操作。
const f2b = (x) => new Uint8Array(new Float64Array([x]).buffer);const b2f = (x) => new Float64Array(x.buffer)[0];// 取得 NaN 的位元組表示const n = f2b(NaN);const m = f2b(NaN);// 改變符號位元,這對 NaN 來說無關緊要n[7] += 2 ** 7;// n[0] += 2**7; 針對大端序處理器const nan2 = b2f(n);console.log(nan2); // NaNconsole.log(Object.is(nan2, NaN)); // trueconsole.log(f2b(NaN)); // Uint8Array(8) [0, 0, 0, 0, 0, 0, 248, 127]console.log(f2b(nan2)); // Uint8Array(8) [0, 0, 0, 0, 0, 0, 248, 255]// 改變第一個位元,這是尾數的最低有效位元,對 NaN 來說無關緊要m[0] = 1;// m[7] = 1; 針對大端序處理器const nan3 = b2f(m);console.log(nan3); // NaNconsole.log(Object.is(nan3, NaN)); // trueconsole.log(f2b(NaN)); // Uint8Array(8) [0, 0, 0, 0, 0, 0, 248, 127]console.log(f2b(nan3)); // Uint8Array(8) [1, 0, 0, 0, 0, 0, 248, 127]靜默避開 NaN
NaN 會透過數學運算傳播,因此通常只需在計算結束時測試一次NaN 即可偵測錯誤情況。唯一會靜默避開NaN 的情況是使用指數為0 的指數運算時,它會立即回傳1 而不測試底數的值。
NaN ** 0 === 1; // true規範
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-value-properties-of-the-global-object-nan> |