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
透過蝦皮分潤計畫,輕鬆賺取零用金!本文分享5-6月實測心得,包含數據流程、實際收入、平臺優點及注意事項,並推薦高分潤商品,教你如何運用空閒時間創造被動收入。
Thumbnail
透過蝦皮分潤計畫,輕鬆賺取零用金!本文分享5-6月實測心得,包含數據流程、實際收入、平臺優點及注意事項,並推薦高分潤商品,教你如何運用空閒時間創造被動收入。
Thumbnail
單身的人有些會養寵物,而我養植物。畢竟寵物離世會傷心,植物沒養好再接再厲就好了~(笑)
Thumbnail
單身的人有些會養寵物,而我養植物。畢竟寵物離世會傷心,植物沒養好再接再厲就好了~(笑)
Thumbnail
不知你有沒有過這種經驗?衛生紙只剩最後一包、洗衣精倒不出來,或電池突然沒電。這次一次補貨,從電池、衛生紙到洗衣精,還順便分享使用心得。更棒的是,搭配蝦皮分潤計畫,愛用品不僅自己用得安心,分享給朋友還能賺回饋。立即使用推薦碼 X5Q344E,輕鬆上手,隨時隨地賺取分潤!
Thumbnail
不知你有沒有過這種經驗?衛生紙只剩最後一包、洗衣精倒不出來,或電池突然沒電。這次一次補貨,從電池、衛生紙到洗衣精,還順便分享使用心得。更棒的是,搭配蝦皮分潤計畫,愛用品不僅自己用得安心,分享給朋友還能賺回饋。立即使用推薦碼 X5Q344E,輕鬆上手,隨時隨地賺取分潤!
Thumbnail
身為一個典型的社畜,上班時間被會議、進度、KPI 塞得滿滿,下班後只想要找一個能夠安靜喘口氣的小角落。對我來說,畫畫就是那個屬於自己的小樹洞。無論是胡亂塗鴉,還是慢慢描繪喜歡的插畫人物,那個專注在筆觸和色彩的過程,就像在幫心靈按摩一樣,讓緊繃的神經慢慢鬆開。
Thumbnail
身為一個典型的社畜,上班時間被會議、進度、KPI 塞得滿滿,下班後只想要找一個能夠安靜喘口氣的小角落。對我來說,畫畫就是那個屬於自己的小樹洞。無論是胡亂塗鴉,還是慢慢描繪喜歡的插畫人物,那個專注在筆觸和色彩的過程,就像在幫心靈按摩一樣,讓緊繃的神經慢慢鬆開。
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 是怎麼被實際運用的!
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News