JavaScript中NaN的祕密
NaN,不是一個數字,是一種特殊的值來代表不可表示的值,使用typeof或其他任何與之比較的處理方式,‘NaN’則會引起一些混亂,
一些操作會導致NaN值的產生。這裡有些例子:
Math.sqrt(-2) Math.log(-1) 0/0 parseFloat('foo')
對於很多JavaScript的初學者來說,它的第一個陷阱是呼叫typeof時返回結果的通常是你想不到的:
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 7提交該方案的
GarlicNaN != NaN
但是當然,解決方案現在已經有了。
讓我們認識一下全域性函式isNaN:
console.log(isNaN(NaN)); // true
唉,不過 isNaN() 也有它自己的很多缺陷呀:
console.log(isNaN('hello')); // true console.log(isNaN(['x'])); // true console.log(isNaN({})); // true
這樣又產生 了很多不同的解決方案。其中一個是利用 了NaN的非反射性質(例如, 看看 Kit Cambridge 的筆記)
var My = { isNaN: function (x) { return x !== x; } }
另外一個例子是先檢查值的型別(防止強制轉換):
My.isNaN = function(x) { return typeof x === 'number' && isNaN(x)};
不過幸運的是,在即將到來的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時,要格外小心了。
附: Poetro 的評論
這是 IEEE 754 定義的NaN標準, 跟JavaScript無關。
"在計算中, NaN, 代表一個非數字, 是用來呈現未定義(undefined)和不可呈現(unrepresentable)的資料型別, 尤其是在浮點計算中。"
"與NaN的比較會一直返回一個無序的結果,甚至跟它自己比較。"
相關文章
- JavaScript原型與繼承的祕密JavaScript原型繼承
- Under the Hood: NaN of JavaScriptNaNJavaScript
- JavaScript NaN 屬性JavaScriptNaN
- 你不知道的JavaScript中的5個JSON祕密功能JavaScriptJSON
- 揭祕JavaScript中“神祕”的this關鍵字JavaScript
- Eventloop的祕密OOP
- JS 中賦值語句的祕密JS賦值
- JavaScript 05筆記(null、undefined、NaN的區別)JavaScript筆記NullUndefinedNaN
- 探索HTTP傳輸中gzip壓縮的祕密HTTP
- 揭曉Java異常體系中的祕密Java
- 網頁文字的祕密網頁
- ZooKeeper 會話的祕密會話
- 隱藏在水印的祕密
- 關於NSUserDefaults的祕密
- 隨機森林的祕密隨機森林
- 請解釋下NaN === NaN的結果NaN
- 美媒:美國AI的祕密武器——中國人才AI
- 解讀爬蟲中HTTP的祕密(高階篇)爬蟲HTTP
- 解讀爬蟲中HTTP的祕密(基礎篇)爬蟲HTTP
- Redis小祕密Redis
- 揭示檢查點的祕密
- “==”、“equals()”、“hashcode()”之間的祕密
- 挖掘Chrome Console的小祕密Chrome
- TCP/IP家族的小祕密TCP
- 《流量的祕密》閱讀分析
- JS中判斷null、undefined與NaN的方法JSNullUndefinedNaN
- WebGL座標系的小祕密Web
- Flutter和原生之間的祕密Flutter
- 判斷NaN的真假NaN
- [pythonskill]Python中NaN和None的詳細比較PythonNaNNone
- 對老闆的怨恨,鑄成了這些遊戲中的黑暗祕密遊戲
- Python變數小祕密Python變數
- JS祕密花園摘要JS
- 行雲全球匯帶你破解中國品牌成功出海的祕密
- 抖音的小遊戲大祕密遊戲
- Brightback:留住客戶的6個祕密
- Mac Idea你不知道的祕密MacIdea
- 谷歌雲端計算的祕密武器谷歌
- Bitmap ImageView大小的一些祕密View