摘要:梁文道暗戀到偷窺本文為讀源碼的第五篇,后續文章會更新到這個倉庫中,歡迎也會同步倉庫的更新,地址本篇分析的是函數。源碼分析來看下的源碼其實的源碼其實就只有這么一句。但是返回的是規定和都為時返回的是。
暗戀之純粹,在于不求結果,完全把自己鎖閉在一個單向的關系里面。——梁文道《暗戀到偷窺》
本文為讀 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
這個規范規定比較的值 x 和 y 都不為 Number 類型,照抄規范如下:
x 的類型不為 Number 類型
y 的類型與 x 的類型一致
如果 x 的類型為 Undefined ,返回 true
如果 x 的類型為 Null ,返回 true
如果 x 的類型為 String,并且 x 和 y 的長度及編碼相同,返回 true,否則返回 false
如果 x 的類型為 Boolean ,并且 x 和 y 同為 true 或同為false ,返回 true,否則返回 false
如果 x 的類型為 Symbol ,并且 x 和 y 具有相同的 Symbol 值,返回 true,否則返回 false
如果 x 和 y 指向同一個對象,返回 true, 否則返回 false
Strict Equality Comparisonjs 中的全等(===)便是遵循這個規范,照搬規范如下:
如果 x 和 y 的類型不同,返回 false
如果 x 的為 Number 類型:
a. 如果 x 為 NaN ,返回 false
b. 如果 y 為 NaN ,返回 false
c. 如果 x 和 y 的數值一致,返回 true
d. 如果 x 為 +0 并且 y 為 -0 ,返回 true
e. 如果 x 為 -0 并且 y 為 +0 ,返回 true
f. 返回 false
按照 SameValueNonNumber 的結果返回
SameValue規范如下:
如果 x 和 y 的類型不同,返回 false
如果 x 的類型為 Number
a. 如果 x 為 NaN 并且 y 為 NaN ,返回 true
b. 如果 x 為 +0 并且 y 為 -0 ,返回 false
c. 如果 x 為 -0 并且 y 為 +0 , 返回 false
d. 如果 x 和 y 的數值一致,返回 true
e. 返回 false
按照 SameValueNonNumber 的結果返回
SameValueZero這個是 eq 遵循的規范,如下:
如果 x 和 y 的類型不同,返回 false
如果 x 的類型為 Number
a. 如果 x 為 NaN 并且 y 為 NaN ,返回 true
b. 如果 x 為 +0 并且 y 為 -0 ,返回 true
c. 如果 x 為 -0 并且 y 為 +0 , 返回 true
d. 如果 x 和 y 的數值一致,返回 true
e. 返回 false
按照 SameValueNonNumber 的結果返回
小結:SameValueNonNumber 是基本,Strict Equality Comparison 、SameValue 和 SameValueZero 只是在對待 +0、-0 和 NaN 上有區別。
源碼分析來看下 eq 的源碼:
function eq(value, other) { return value === other || (value !== value && other !== other) }
其實eq 的源碼其實就只有這么一句。
既然 eq 遵循的是 SameValueZero 規范,那就將源碼來拆解一下,看它是怎樣符合規范的。
首先,看第一部分:
value === other
就是這么一段,符合的是 Strict Equality Comparison 規范,通過對比可以發現, Strict Equality Comparison 和 SameValueZero 只在對待 NaN 上有區別。
Strict Equality Comparison 規定就算 x 和 y 都為 NaN 時,返回的是 false, NaN === NaN 返回的就是 false。但是 SameValueZero 返回的是規定 x 和 y 都為 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 的缺陷,es6 在 Number 對象上擴展了 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 源碼的第六篇,后續文章會更新到這個倉庫中,歡迎 star:pocket-lodash gitbook也會同步倉庫的更新...
摘要:依賴源碼分析之緩存使用方式的進一步封裝源碼分析之源碼分析之源碼分析之的實現源碼分析之源碼分析的調用如果有傳遞,則先調用,使用生成要比較數組的映射數組。循環完畢,沒有在第二個數組中發現相同的項時,將該項存入數組中。 外部世界那些破舊與貧困的樣子,可以使我內心世界得到平衡。——卡爾維諾《煙云》 本文為讀 lodash 源碼的第十七篇,后續文章會更新到這個倉庫中,歡迎 star:pocke...
摘要:到這里,源碼分析完了。但是,有兩個致命的特性的遍歷不能保證順序會遍歷所有可枚舉屬性,包括繼承的屬性。的遍歷順序依賴于執行環境,不同執行環境的實現方式可能會不一樣。 小時候,鄉愁是一枚小小的郵票, 我在這頭, 母親在那頭。 長大后,鄉愁是一張窄窄的船票, 我在這頭, 新娘在那頭。 后來啊, 鄉愁是一方矮矮的墳墓, 我在外頭, 母親在里頭。 而現在, 鄉愁是一灣淺淺的海峽, 我在這頭, 大...
摘要:首先是通過創建一個函數,然后向其傳遞參與計算的值,也就是說應該是返回一個函數,并且有兩個參數。事實上就是這樣,返回值是一個,是被加數,是加數。 源碼注釋版 這一組函數都是數學計算相關的,主要分為三類: 加減乘除:add、subtract、multiply、divide 求最大最小平均值:max、maxBy、min、minBy、sum、sumBy、mean、meanBy 小數的四舍...
摘要:今天要講的,是我從的源碼實現文件中學到的幾個很基礎,卻又容易被忽略的知識點。在函數式編程中,函數是一等公民,它可以只是根據參數,做簡單的組合操作,再作為別的函數的返回值。所以,閱讀源碼,是一種很棒的重溫基礎知識的方式。 showImg(https://segmentfault.com/img/bVbpTSY?w=750&h=422); 前言 上一篇文章 「前端面試題系列8」數組去重(1...
閱讀 684·2021-09-30 09:47
閱讀 2875·2021-09-04 16:40
閱讀 860·2019-08-30 13:18
閱讀 3455·2019-08-29 16:22
閱讀 1560·2019-08-29 12:36
閱讀 591·2019-08-29 11:11
閱讀 1479·2019-08-26 13:47
閱讀 1134·2019-08-26 13:32