JavaScript 中的 NaN

做者:Dmitri Pavlutin

翻譯:瘋狂的技術宅javascript

原文:https://dmitripavlutin.com/na...前端

未經容許嚴禁轉載java

JavaScript 中的數字類型包含整數和浮點數:程序員

const integer = 4;
const float = 1.5;

typeof integer; // => 'number'
typeof float;   // => 'number'

另外還有 2 個特殊的數字值:Infinity(比其餘任何數字都大的數字)和 NaN(表示「Not A Number」概念):面試

const infinite = Infinity;
const faulty = NaN;

typeof infinite; // => 'number'
typeof faulty;   // => 'number'

雖然直接使用 NaN 的狀況不多見,但在對數字進行無效的操做後卻會使人驚訝地出現。segmentfault

讓咱們仔細看看 NaN 特殊值:如何檢查變量是否具備 NaN,並瞭解怎樣建立「Not A Number」值。服務器

NaN number

JavaScript 中的數字類型是全部數字值的集合,包括 「Not A Number」,正無窮和負無窮。微信

可使用特殊表達式 NaN 、全局對象或 Number 函數的屬性來訪問「Not A Number」:多線程

typeof NaN;        // => 'number'
typeof window.NaN; // => 'number'
typeof Number.NaN; // => 'number'

儘管具備數字類型,但「Not A Number」是不表明實數的值。NaN 可用於表示錯誤的數字運算。app

例如,將數字與 undefined 相乘不是有效操做,所以結果爲 NaN

1 * undefined;     // => NaN

一樣嘗試解析無效的數字字符串(如 'Joker')也會致使 NaN

parseInt('Joker', 10); // => NaN

檢查 NaN 是否相等

NaN有趣的特性是,即便使用 NaN 自己,它也不等於任何值:

NaN === NaN; // => false

此行爲對於檢測變量是否爲 NaN 很是有用:

const someNumber = NaN;

if (someNumber !== someNumber) {  console.log('Is NaN');
} else {
  console.log('Is Not NaN');
}

// logs "Is NaN"

僅當 someNumberNaN 時,someNumber !== someNumber 表達式纔是 true。所以,以上代碼片斷輸出到控制檯的結果是 "Is NaN"

JavaScript 經過內置函數來檢測 NaNisNaN()Number.isNaN()

isNaN(NaN); // => true
isNaN(1);   // => false

Number.isNaN(NaN); // => true
Number.isNaN(1);   // => false

這些函數之間的區別在於,Number.isNaN() 不會將其參數轉換爲數字:

isNaN('Joker12');        // => true
Number.isNaN('Joker12'); // => false

isNaN('Joker12') 將參數 'Joker12' 轉換爲數字,即 NaN。所以該函數返回 true

另外一方面,Number.isNaN('Joker12') 會檢查參數是否爲 NaN 而不進行轉換。該函數返回 false ,由於'Joker12' 不等於 NaN

致使 NaN 的運算

1 解析數字

在 JavaScript 中,你能夠將字符串形式的數字轉換爲數字。

例如你能夠輕鬆地將字符串 '1.5' 轉換爲浮點數 1.5

const numberString = '1.5';
const number = parseFloat(numberString);

number; // => 1.5

當字符串不能被轉換爲數字時,解析函數返回 NaN :表示解析失敗。這裏有些例子:

parseFloat('Joker12.5'); // => NaN
parseInt('Joker12', 10); // => NaN
Number('Joker12');       // => NaN

解析數字時,最好先確認解析結果是否爲 NaN

let inputToParse = 'Invalid10';
let number;

number = parseInt(inputToParse, 10);
if (isNaN(number)) {  number = 0;
}

number; // => 0

解析 inputToParse 失敗,所以 parseInt(inputToParse, 10)返回 NaN。條件 if (isNaN(number))true,而且將 number 賦值爲 0

2 undefined 做爲操做數

undefined 用做加法、乘法等算術運算中的操做數會生成 NaN

例如:

function getFontSize(style) {
  return style.fontSize;
}

const fontSize = getFontSize({ size: 16 }) * 2;
const doubledFontSize = fontSize * 2;

doubledFontSize; // => NaN

getFontSize() 是從樣式對象訪問 fontSize 屬性的函數。調用 getFontSize({ size: 16 }) 時,結果是undefined(在 { size: 16 } 對象中不存在 fontSize 屬性)。

fontSize * 2 被評估爲 undefined * 2,結果爲 NaN

當把缺乏的屬性或返回 undefined 的函數用做算術運算中的值時,將生成 「Not A Number」。

防止 NaN 的好方法是確保 undefined 不會進行算術運算,須要隨時檢查。

3 NaN 做爲操做數

當算數運算的操做數爲 NaN 時,也會生成NaN 值:

1 + NaN; // => NaN
2 * NaN; // => NaN

NaN 遍佈算術運算:

let invalidNumber = 1 * undefined;
let result = 1;
result += invalidNumber; // appendresult *= 2;             // duplicate
result++;                // increment

result; // => NaN

在將 invalidNumber 值(具備 'NaN')附加到 result以後,會破壞對 result 變量的操做。

4 Indeterminate 形式

當算術運算採用不肯定形式時,將會產生 NaN 值。

0/0Infinity/Infinity 這樣的的除法運算:

0 / 0;               // => NaN
Infinity / Infinity; // => NaN

0Infinity 的乘法運算:

0 * Infinity; // => NaN

帶有不一樣符號的 Infinity 的加法:

-Infinity + Infinity; // => NaN

5 無效的數學函數參數

負數的平方根:

Math.pow(-2, 0.5); // => NaN
(-2) ** 0.5;       // => NaN

或負數的對數:

Math.log2(-2); // => NaN

總結

JavaScript 中用 NaN 表示的的「Not A Number」概念對於表示錯誤的數字運算頗有用。

即便是 NaN 自己也不等於任何值。檢查變量是否包含 NaN 的建議方法是使用 Number.isNaN(value)

將字符串形式的數字轉換爲數字類型失敗時,可能會致使顯示「Not A Number」。檢查 parseInt()parseFloat()Number() 是否返回了 NaN 是個好主意。

undefinedNaN 做爲算術運算中的操做數一般會致使 NaN。正確處理 undefined(爲缺乏的屬性提供默認值)是防止這種狀況的好方法。

數學函數的不肯定形式或無效參數也會致使 「Not A Number」。可是這些狀況不多發生。
這是個人務實建議:出現了 NaN?趕快檢查是否存在 undefined


本文首發微信公衆號:前端先鋒

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

歡迎繼續閱讀本專欄其它高贊文章:


相關文章
相關標籤/搜索