国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

lodash源碼分析之NaN不是NaN

gaomysion / 3126人閱讀

摘要:梁文道暗戀到偷窺本文為讀源碼的第五篇,后續文章會更新到這個倉庫中,歡迎也會同步倉庫的更新,地址本篇分析的是函數。源碼分析來看下的源碼其實的源碼其實就只有這么一句。但是返回的是規定和都為時返回的是。

暗戀之純粹,在于不求結果,完全把自己鎖閉在一個單向的關系里面。

——梁文道《暗戀到偷窺》

本文為讀 lodash 源碼的第五篇,后續文章會更新到這個倉庫中,歡迎 star:pocket-lodash

gitbook也會同步倉庫的更新,gitbook地址:pocket-lodash

本篇分析的是 eq 函數。

作用與用法

eq 函數用來比較兩個值是否相等。遵循的是 SameValueZero 規范。

var obj1 = {test: 1}
var obj2 = {test: 1}
var obj3 = obj1
_.eq(1,1) // true
_.eq(+0, -0) // true
_.eq(obj1, obj3) // true
_.eq(obj1, obj2) // false
_.eq(NaN, NaN) // false
幾個比較規范 SameValueNonNumber

這個規范規定比較的值 xy 都不為 Number 類型,照抄規范如下:

x 的類型不為 Number 類型

y 的類型與 x 的類型一致

如果 x 的類型為 Undefined ,返回 true

如果 x 的類型為 Null ,返回 true

如果 x 的類型為 String,并且 xy 的長度及編碼相同,返回 true,否則返回 false

如果 x 的類型為 Boolean ,并且 xy 同為 true 或同為false ,返回 true,否則返回 false

如果 x 的類型為 Symbol ,并且 xy 具有相同的 Symbol 值,返回 true,否則返回 false

如果 xy 指向同一個對象,返回 true, 否則返回 false

Strict Equality Comparison

js 中的全等(===)便是遵循這個規范,照搬規范如下:

如果 xy 的類型不同,返回 false

如果 x 的為 Number 類型:

a. 如果 xNaN ,返回 false

b. 如果 yNaN ,返回 false

c. 如果 xy 的數值一致,返回 true

d. 如果 x+0 并且 y-0 ,返回 true

e. 如果 x-0 并且 y+0 ,返回 true

f. 返回 false

按照 SameValueNonNumber 的結果返回

SameValue

規范如下:

如果 xy 的類型不同,返回 false

如果 x 的類型為 Number

a. 如果 xNaN 并且 yNaN ,返回 true

b. 如果 x+0 并且 y-0 ,返回 false

c. 如果 x-0 并且 y+0 , 返回 false

d. 如果 xy 的數值一致,返回 true

e. 返回 false

按照 SameValueNonNumber 的結果返回

SameValueZero

這個是 eq 遵循的規范,如下:

如果 xy 的類型不同,返回 false

如果 x 的類型為 Number

a. 如果 xNaN 并且 yNaN ,返回 true

b. 如果 x+0 并且 y-0 ,返回 true

c. 如果 x-0 并且 y+0 , 返回 true

d. 如果 xy 的數值一致,返回 true

e. 返回 false

按照 SameValueNonNumber 的結果返回

小結:SameValueNonNumber 是基本,Strict Equality ComparisonSameValueSameValueZero 只是在對待 +0-0NaN 上有區別。

源碼分析

來看下 eq 的源碼:

function eq(value, other) {
  return value === other || (value !== value && other !== other)
}

其實eq 的源碼其實就只有這么一句。

既然 eq 遵循的是 SameValueZero 規范,那就將源碼來拆解一下,看它是怎樣符合規范的。

首先,看第一部分:

value === other

就是這么一段,符合的是 Strict Equality Comparison 規范,通過對比可以發現, Strict Equality ComparisonSameValueZero 只在對待 NaN 上有區別。

Strict Equality Comparison 規定就算 xy 都為 NaN 時,返回的是 falseNaN === NaN 返回的就是 false。但是 SameValueZero 返回的是規定 xy 都為 NaN 時返回的是 true。因此只需要在 Strict Equality Comparison 的基礎上處理 NaN 就可以了。

下面這段便是處理 NaN 的:

(value !== value && other !== other)

在 js 中,只有 NaN 和自身是不相等的,當兩個需要比較的值都是和自身不相等時,表明這兩個值都為 NaN,返回 true

這樣便遵循了 SameValueZero 的比較實現。

可以用Object.is()嗎?

Object.is(NaN, NaN) 返回的是 true ,所以 eq 同樣可以改成:

function eq(value, other) {
  return value === other || Object.is(value, other)
}

Object.is 同樣是比較兩個值是否一樣,但是 Object.is(+0, -0) 返回的是 false, 它遵循是的 SameValue 規范,因此不可以直接用 Object.is 替代 eq

可以用isNaN()嗎?

還有個 isNaN 的全局方法,可以用來判斷一個值是否為 NaN。例如 isNaN(NaN) 會返回 true ,那 eq 是否可以改成以下形式呢?

function eq(value, other) {
  return value === other || (isNaN(value) && isNaN(other))
}

答案是:不可以!

isNaN 有一個很怪異的行為,如果傳入的參數不為 Number 類型,會嘗試轉換成 Number 類型之后再做是否為 NaN 的判斷。所以類似 isNaN("notNaN") 返回的也是 true ,因為字符串 notNaN 會先被轉換成 NaN 再做判斷,這不是我們想要的結果。

可以用Number.isNaN()嗎

為了修復 isNaN 的缺陷,es6Number 對象上擴展了 isNaN 方法,只有是 NaN 時才會返回 true,因此用 Number.isNaN 來判斷是安全的。所以 eq 同樣可以改成以下形式:

function eq(value, other) {
  return value === other || (Number.isNaN(value) && Number.isNaN(other))
}
參考

ECMAScript? 2016 Language Specification

MDN:Number.isNaN()

MDN:isNaN()

License

署名-非商業性使用-禁止演繹 4.0 國際 (CC BY-NC-ND 4.0)

最后,所有文章都會同步發送到微信公眾號上,歡迎關注,歡迎提意見:

作者:對角另一面

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/90643.html

相關文章

  • lodash源碼分析自減的兩種形式

    摘要:作用與用法是的內部函數,之前在源碼分析之緩存介紹過一種這樣的數據結構這是一個二維數組,每項中的第一項作為緩存對象的,第二項為緩存的值。 這個世界需要一個特定的惡人,可以供人們指名道姓,千夫所指:全都怪你。——村上春樹《當我談跑步時我談些什么》 本文為讀 lodash 源碼的第六篇,后續文章會更新到這個倉庫中,歡迎 star:pocket-lodash gitbook也會同步倉庫的更新...

    Keven 評論0 收藏0
  • lodash源碼分析數組的差集

    摘要:依賴源碼分析之緩存使用方式的進一步封裝源碼分析之源碼分析之源碼分析之的實現源碼分析之源碼分析的調用如果有傳遞,則先調用,使用生成要比較數組的映射數組。循環完畢,沒有在第二個數組中發現相同的項時,將該項存入數組中。 外部世界那些破舊與貧困的樣子,可以使我內心世界得到平衡。——卡爾維諾《煙云》 本文為讀 lodash 源碼的第十七篇,后續文章會更新到這個倉庫中,歡迎 star:pocke...

    Noodles 評論0 收藏0
  • lodash源碼分析compact中的遍歷

    摘要:到這里,源碼分析完了。但是,有兩個致命的特性的遍歷不能保證順序會遍歷所有可枚舉屬性,包括繼承的屬性。的遍歷順序依賴于執行環境,不同執行環境的實現方式可能會不一樣。 小時候,鄉愁是一枚小小的郵票, 我在這頭, 母親在那頭。 長大后,鄉愁是一張窄窄的船票, 我在這頭, 新娘在那頭。 后來啊, 鄉愁是一方矮矮的墳墓, 我在外頭, 母親在里頭。 而現在, 鄉愁是一灣淺淺的海峽, 我在這頭, 大...

    dmlllll 評論0 收藏0
  • 我來閱讀lodash源碼——Math(一)

    摘要:首先是通過創建一個函數,然后向其傳遞參與計算的值,也就是說應該是返回一個函數,并且有兩個參數。事實上就是這樣,返回值是一個,是被加數,是加數。 源碼注釋版 這一組函數都是數學計算相關的,主要分為三類: 加減乘除:add、subtract、multiply、divide 求最大最小平均值:max、maxBy、min、minBy、sum、sumBy、mean、meanBy 小數的四舍...

    levinit 評論0 收藏0
  • 「讀懂源碼系列2」我從 lodash 源碼中學到的幾個知識點

    摘要:今天要講的,是我從的源碼實現文件中學到的幾個很基礎,卻又容易被忽略的知識點。在函數式編程中,函數是一等公民,它可以只是根據參數,做簡單的組合操作,再作為別的函數的返回值。所以,閱讀源碼,是一種很棒的重溫基礎知識的方式。 showImg(https://segmentfault.com/img/bVbpTSY?w=750&h=422); 前言 上一篇文章 「前端面試題系列8」數組去重(1...

    Amio 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<