此部分為該函式的文件說明,簡單地描述了其用途,傳參型別介面與使用範例等資訊。特別看到第 4 行的 note 直接說明了這個函式與全域下那個遇到 undefined 或其他非數值時會回傳 true 的 isNaN
不同。
// An `NaN` primitive is the only value that is not equal to itself.
第 30 行註解指出,NaN 是 JavaScript 中唯一一個不等於自身的值。這意味著如果一個值不等於自身,它一定是 NaN。例如:
NaN === NaN // false
請特別注意這個特性,因為這是 Lodash 執行檢測 NaN 的核心原理之一,後續也會反覆提到。
// Perform the `toStringTag` check first to avoid errors with some
// ActiveX objects in IE.
第 31 至 32 行註解解釋了在 IE 瀏覽器中的某些情況下,如果值來自 ActiveX 對象,可能會引發錯誤。因此,Lodash 在檢查 value 是否為 NaN 之前,會先通過 isNumber
來檢查它是否為數值型別,這樣可以避免非數值型別進入後續的判斷,減少潛在的錯誤。
return isNumber(value) && value != +value
這行源碼包含兩個條件:
isNumber(value)
:確認 value 是否為數值型別。isNumber
是 Lodash 中另一個函式,專門檢查變數是否為數值。value != +value
:這是該函式的核心邏輯。它嘗試將 value 強制轉型為數值型態再進行比較,並檢查 value 是否不等於自身。在該函式中,Lodash 先是檢查 value 的型別,若非數值就直接返回 false。接著進行 NaN 檢查,若 value 是數值且符合 value != +value
(也就是不等於自身),則確認為 NaN,返回 true。
前面我們提過 NaN 有一個特性就是它不等於它自己。
NaN compares unequal (via ==, !=, ===, and !==) to any other value — including to another NaN value.
因此 Lodash 利用此特性當 value 是 NaN 時,它會滿足 value != +value
條件。除此之外,任何數值類型(例如 0、1,Infinity 等)都不會滿足這個條件。
const foo = 0
console.log(foo != +foo) // false
const bar = NaN
console.log(bar != +bar) // true
這邊你可能會注意到一個陌生的寫法 +value
,它的目的是強制將 value 轉為數值型別。既然使用 isNumber
檢查 value 了,又為什麼要操作轉型別呢?讓我們深入探討其原因。
+value
是一種確保 value 參與數值比較時行為一致的方式。雖然 isNumber
已經確認 value 是數值型別,但在 JavaScript 中,數值型別仍然可能包含特殊的 NaN 或 Infinity。而透過 +value
在數值型別的操作中會保持一致的行為,就算遇到一些極端數值情況(例如 Number('NaN')
),也能使運算更具穩定性。value != +value
利用了這個特性。即便有些情況下 value 是數值型別(如來自不同的運算結果或隱式轉換),這個寫法都能確保判斷的結果正確。回到 Lodash 源碼本身,就目前的函式內容來看,在大多數情境下不寫 +
仍然會得到相同的結果,但其實補上這種寫法會更嚴謹,從而避免某些潛在的轉型錯誤。
_.isNaN
是 Lodash 函式庫提供的一個 utility,用來檢查數值是否為 NaN。該函式尤其適合用於處理數值陣列或檢查計算結果。當數值經過多次運算而可能出現 NaN 的情況時(例如在資料處理和數據分析中)它能幫助我們有效地檢查和排除無效數值。
這在 JavaScript 開發中非常有用,因為內建的 isNaN
函式存在部分缺陷,特別是在處理非數值類型時。但 Lodash 提供的 _.isNaN
方法能讓這個檢查情境更直觀與安全。
declare function isNaN(value: any): boolean;
const result1 = _.isNaN(NaN) // true
const result2 = _.isNaN(4) // false
const result3 = _.isNaN('hello') // false
const result4 = _.isNaN(undefined) // false
// 請注意此處的 isNaN 是 nuxt-lodash 的,而非原生 isNaN
const result1 = isNaN(NaN) // true
const result2 = isNaN(4) // false
const result3 = isNaN('hello') // false
const result4 = isNaN(undefined) // false
另外當你需要過濾掉 NaN 值時,也可以搭配 Lodash 的 _.filter
進行過濾:
const values = [1, NaN, 3, NaN, 5]
const filteredValues = _.filter(values, value => !_.isNaN(value))
console.log(filteredValues) // [1, 3, 5]
在 JavaScript 原生 isNaN
函式中,非數值(如字串或物件)會被強制轉為數字再進行檢查,這會導致一些誤判。例如:
isNaN('hello') // true,因為 'hello' 轉為數字後結果為 NaN
而 Lodash 的 isNaN 僅在值真的等於 NaN 時才會返回 true,因此它不會受強制轉型的影響。例如:
_.isNaN('hello') // false,因為 'hello' 並非 NaN
Lodash 的 isNaN
函式提供了我們一個簡單而準確的方法來檢查是否為 NaN。
它的重點在於結合 isNumber
和 value != +value
的判斷來進行精準檢測,同時避免了 JavaScript 原生 isNaN
的弱點。這種設計讓它能在 JavaScript 各種環境中準確地識別 NaN 且不會受到非數值類型的影響,使得它在開發中更為安全並提升我們程式碼的嚴謹性。
Cheng's murmur
你各位被教召了嗎,我被教召了⋯