Lodash 源碼導讀 - isNaN 篇

更新於 發佈於 閱讀時間約 8 分鐘
raw-image


完整源碼

撰稿時版本為 v4.17.15

撰稿時版本為 v4.17.15


解析源碼

Line 1 ~ 28 註解部分

此部分為該函式的文件說明,簡單地描述了其用途,傳參型別介面與使用範例等資訊。特別看到第 4 行的 note 直接說明了這個函式與全域下那個遇到 undefined 或其他非數值時會回傳 true 的 isNaN 不同。


Line 30 ~ 32 註解部分

// 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 來檢查它是否為數值型別,這樣可以避免非數值型別進入後續的判斷,減少潛在的錯誤。


Line 33 函式內容

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')),也能使運算更具穩定性。
  • 進一步強化 NaN 檢測:在 JavaScript 中,NaN 是唯一一個不等於自身的值,而 value != +value 利用了這個特性。即便有些情況下 value 是數值型別(如來自不同的運算結果或隱式轉換),這個寫法都能確保判斷的結果正確。

回到 Lodash 源碼本身,就目前的函式內容來看,在大多數情境下不寫 + 仍然會得到相同的結果,但其實補上這種寫法會更嚴謹,從而避免某些潛在的轉型錯誤。


實務說明

情境用途

_.isNaN 是 Lodash 函式庫提供的一個 utility,用來檢查數值是否為 NaN。該函式尤其適合用於處理數值陣列或檢查計算結果。當數值經過多次運算而可能出現 NaN 的情況時(例如在資料處理和數據分析中)它能幫助我們有效地檢查和排除無效數值。

這在 JavaScript 開發中非常有用,因為內建的 isNaN 函式存在部分缺陷,特別是在處理非數值類型時。但 Lodash 提供的 _.isNaN 方法能讓這個檢查情境更直觀與安全。


型別定義

declare function isNaN(value: any): boolean;


基本用法

  • 原始 Lodash 版本
const result1 = _.isNaN(NaN) // true
const result2 = _.isNaN(4) // false
const result3 = _.isNaN('hello') // false
const result4 = _.isNaN(undefined) // false
  • nuxt-lodash 版本
// 請注意此處的 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]

與原生 isNaN 的區別

在 JavaScript 原生 isNaN 函式中,非數值(如字串或物件)會被強制轉為數字再進行檢查,這會導致一些誤判。例如:

isNaN('hello') // true,因為 'hello' 轉為數字後結果為 NaN


而 Lodash 的 isNaN 僅在值真的等於 NaN 時才會返回 true,因此它不會受強制轉型的影響。例如:

_.isNaN('hello') // false,因為 'hello' 並非 NaN


總結

Lodash 的 isNaN 函式提供了我們一個簡單而準確的方法來檢查是否為 NaN。

它的重點在於結合 isNumbervalue != +value 的判斷來進行精準檢測,同時避免了 JavaScript 原生 isNaN 的弱點。這種設計讓它能在 JavaScript 各種環境中準確地識別 NaN 且不會受到非數值類型的影響,使得它在開發中更為安全並提升我們程式碼的嚴謹性。


Cheng's murmur

你各位被教召了嗎,我被教召了⋯
留言
avatar-img
留言分享你的想法!
avatar-img
Cheng's
2會員
6內容數
生活就是 早上 8 點的文湖線;晚上 8 點的 New York Sour;帶著一台 GR3X 意興闌珊的漫步;嚮往著午後草皮上陪拉布拉多 🐶 玩耍;拿起似有似無的筆開始敲打創作。
你可能也想看
Thumbnail
TOMICA第一波推出吉伊卡哇聯名小車車的時候馬上就被搶購一空,一直很扼腕當時沒有趕緊入手。前陣子閒來無事逛蝦皮,突然發現幾家商場都又開始重新上架,價格也都回到正常水準,估計是官方又再補了一批貨,想都沒想就立刻下單! 同文也跟大家分享近期蝦皮購物紀錄、好用推薦、蝦皮分潤計畫的聯盟行銷!
Thumbnail
TOMICA第一波推出吉伊卡哇聯名小車車的時候馬上就被搶購一空,一直很扼腕當時沒有趕緊入手。前陣子閒來無事逛蝦皮,突然發現幾家商場都又開始重新上架,價格也都回到正常水準,估計是官方又再補了一批貨,想都沒想就立刻下單! 同文也跟大家分享近期蝦皮購物紀錄、好用推薦、蝦皮分潤計畫的聯盟行銷!
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
在 JavaScript 中,邏輯運算子和比較運算子是用於條件判斷的重要工具。 它們常被用來進行邏輯運算和比較數值或變數,進一步決定程式的執行流程。
Thumbnail
在 JavaScript 中,邏輯運算子和比較運算子是用於條件判斷的重要工具。 它們常被用來進行邏輯運算和比較數值或變數,進一步決定程式的執行流程。
Thumbnail
2.0 上古漢語的特殊結構 2.3 之乎者也 —  也 (矣﹑焉) 2.3.1 也 一﹕初探之四 現在讓我們從函數引申出來的函子/論元觀點來解析上述「也」字的用法。用初級計算機科學編程的語言來說,函子就是一個具有函數功能的物件 (object),方便我們使用﹔它的功能就是讓我們可以召喚
Thumbnail
2.0 上古漢語的特殊結構 2.3 之乎者也 —  也 (矣﹑焉) 2.3.1 也 一﹕初探之四 現在讓我們從函數引申出來的函子/論元觀點來解析上述「也」字的用法。用初級計算機科學編程的語言來說,函子就是一個具有函數功能的物件 (object),方便我們使用﹔它的功能就是讓我們可以召喚
Thumbnail
1.0 從函數到函算語法 1.4 函算語法 1.4.1 語法範疇理論導論 1.4.2 函算語法與函數概念 二 關於函數的演變和弗雷格對函數的看法,前面的 1.2 節和 1.3 節已經談論了不少。 由於函數在數學﹑邏輯學﹑計算語言學極為重要,更且是本書闡述的語法的中心概念,因此有必要再略作
Thumbnail
1.0 從函數到函算語法 1.4 函算語法 1.4.1 語法範疇理論導論 1.4.2 函算語法與函數概念 二 關於函數的演變和弗雷格對函數的看法,前面的 1.2 節和 1.3 節已經談論了不少。 由於函數在數學﹑邏輯學﹑計算語言學極為重要,更且是本書闡述的語法的中心概念,因此有必要再略作
Thumbnail
1.0 從函數到函算語法 1.4 函算語法 1.4.1 語法範疇理論導論 七 指派範疇是第一步, 第二步是設定推導規則。 推導規則的作用是對某一給定的表式63 進行判定,看它是否一個貫通的表式(或詞構)。就上述英語例句而言,我們只需一個簡單的單向通則 (general rule)﹕6
Thumbnail
1.0 從函數到函算語法 1.4 函算語法 1.4.1 語法範疇理論導論 七 指派範疇是第一步, 第二步是設定推導規則。 推導規則的作用是對某一給定的表式63 進行判定,看它是否一個貫通的表式(或詞構)。就上述英語例句而言,我們只需一個簡單的單向通則 (general rule)﹕6
Thumbnail
1.0 從函數到函算語法 1.2 函數概念小史 1.2.1 中譯的來源 數學中函數概念的重要性難以盡書,亦很難想像沒有函數概念的數學可以走多遠。誇張一點,我們可以說很大部份的數學都是按函數概念操作的。但少有人留意到,在某個意義上,函數可說是數學語言的一個語構處理。 漢語「函數」一詞乃
Thumbnail
1.0 從函數到函算語法 1.2 函數概念小史 1.2.1 中譯的來源 數學中函數概念的重要性難以盡書,亦很難想像沒有函數概念的數學可以走多遠。誇張一點,我們可以說很大部份的數學都是按函數概念操作的。但少有人留意到,在某個意義上,函數可說是數學語言的一個語構處理。 漢語「函數」一詞乃
Thumbnail
直觀理解 導數:考慮的是單一變數的函數,描述的是函數在某點的斜率或變化率。 偏導數:考慮的是多變數函數,描述的是函數在某個變數變化時的變化率,其他變數保持不變。  (針對各維度的調整 或者稱變化 你要調多少) 應用 導數:在物理學中應用廣泛,例如描述速度和加速度。 偏導數:在多變量分析、優
Thumbnail
直觀理解 導數:考慮的是單一變數的函數,描述的是函數在某點的斜率或變化率。 偏導數:考慮的是多變數函數,描述的是函數在某個變數變化時的變化率,其他變數保持不變。  (針對各維度的調整 或者稱變化 你要調多少) 應用 導數:在物理學中應用廣泛,例如描述速度和加速度。 偏導數:在多變量分析、優
Thumbnail
接下來來看 AND、OR、NOT 是怎麼被實際運用的!
Thumbnail
接下來來看 AND、OR、NOT 是怎麼被實際運用的!
Thumbnail
你會在程式裡面寫函數嗎? 通常寫函數的第一個問題,就是要給函數取名字。 名字取得不好,後來調用函數不自然,就會拖垮整個寫程式的效率。 為函數命名,也是一門技術,好的函數命名,就能提高函數被重複使用的頻率。 然而,也是在某些情況下,我們需要「一次性函數」。 沒錯,用完即丟的函數。
Thumbnail
你會在程式裡面寫函數嗎? 通常寫函數的第一個問題,就是要給函數取名字。 名字取得不好,後來調用函數不自然,就會拖垮整個寫程式的效率。 為函數命名,也是一門技術,好的函數命名,就能提高函數被重複使用的頻率。 然而,也是在某些情況下,我們需要「一次性函數」。 沒錯,用完即丟的函數。
Thumbnail
這篇文章將會講述 if 判斷式的簡寫與可讀性維護。
Thumbnail
這篇文章將會講述 if 判斷式的簡寫與可讀性維護。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News