JavaScript中不可不知的NaN問題
阿新 • • 發佈:2019-02-16
經常在javascript程式碼除錯過程中會出現一個莫名其妙的“NaN”,到底它是表示什麼呢?通過這篇文章我們來探析一下NaN的祕密。NaN,是Not a Number的縮寫, NaN 用於處理計算中出現的錯誤情況,如果參與計算的值不是一個數字,計算結果就會出現NaN。
一些操作會導致NaN值的產生。這裡有些例子:
Math.sqrt(-2) Math.log(-1) 0/0 parseFloat('foo')
我們可以嘗試使用typeof來確定NaN的型別,返回結果可能是出乎你的意料的:
console.log(typeof NaN); // 'number'
這情情況下,NaN並不意味著是一個數字,它的型別是數字。
保持冷靜,因為下面還有很多混亂的地方。讓我們比較兩個NaN:
var x = Math.sqrt(-2); var y = Math.log(-1); console.log(x == y); // false
也許這是因為我們沒有使用嚴格等價(===)操作?顯然不是。
var x = Math.sqrt(-2); var y = Math.log(-1); console.log(x === y); // false
好吧!難道是因為這兩個NaN是從不同的操作產生出來的?那麼這樣...
var x = Math.sqrt(-2); var y = Math.sqrt(-2); console.log(x == y); // false
再瘋狂一點
var x = Math.sqrt(-2); console.log(x == x); // false
直接比較兩個NaN呢?
console.log(NaN === NaN); // false
因為有很多方法來表示一個非數字,所以一個非數字不會等於另一個為NaN的非數字,它還是有一定道理的。不過這也是我為什麼時而崩潰的原因:
這是對你的提醒,NaN的意思是“不為NaN".
— Ariya Hidayat (@AriyaHidayat)
不過幸運的是,在即將到來的ECMAScript 6中, 有一個Number.isNaN() 方法提供可靠的NaN值檢測。(隨便說下,你已經可以在最新版的Chrome和firefox中使用這個方法了)。在2014年4月的規範草稿中,有著如下記載:
當傳入一個數字引數並呼叫 Number.isNaN 時,會進行以下幾步:
1. 如果Type(number) 不是數字, 返回 false.
2. 如果數字是NaN, 返回true.
3. 其他情況,返回false.
換句話說,只有在引數是真正的NaN時,才會返回true
console.log(Number.isNaN(NaN)); // true console.log(Number.isNaN(Math.sqrt(-2))); // true console.log(Number.isNaN('hello')); // false console.log(Number.isNaN(['x'])); // false console.log(Number.isNaN({})); // false
"在計算中, NaN, 代表一個非數字, 是用來呈現未定義(undefined)和不可呈現(unrepresentable)的資料型別, 尤其是在浮點計算中。"
"與NaN的比較會一直返回一個無序的結果,甚至跟它自己比較。"