摘要:梁文道暗戀到偷窺本文為讀源碼的第五篇,后續(xù)文章會(huì)更新到這個(gè)倉庫中,歡迎也會(huì)同步倉庫的更新,地址本篇分析的是函數(shù)。源碼分析來看下的源碼其實(shí)的源碼其實(shí)就只有這么一句。但是返回的是規(guī)定和都為時(shí)返回的是。
暗戀之純粹,在于不求結(jié)果,完全把自己鎖閉在一個(gè)單向的關(guān)系里面。——梁文道《暗戀到偷窺》
本文為讀 lodash 源碼的第五篇,后續(xù)文章會(huì)更新到這個(gè)倉庫中,歡迎 star:pocket-lodash
gitbook也會(huì)同步倉庫的更新,gitbook地址:pocket-lodash
本篇分析的是 eq 函數(shù)。
作用與用法eq 函數(shù)用來比較兩個(gè)值是否相等。遵循的是 SameValueZero 規(guī)范。
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幾個(gè)比較規(guī)范 SameValueNonNumber
這個(gè)規(guī)范規(guī)定比較的值 x 和 y 都不為 Number 類型,照抄規(guī)范如下:
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 指向同一個(gè)對象,返回 true, 否則返回 false
Strict Equality Comparisonjs 中的全等(===)便是遵循這個(gè)規(guī)范,照搬規(guī)范如下:
如果 x 和 y 的類型不同,返回 false
如果 x 的為 Number 類型:
a. 如果 x 為 NaN ,返回 false
b. 如果 y 為 NaN ,返回 false
c. 如果 x 和 y 的數(shù)值一致,返回 true
d. 如果 x 為 +0 并且 y 為 -0 ,返回 true
e. 如果 x 為 -0 并且 y 為 +0 ,返回 true
f. 返回 false
按照 SameValueNonNumber 的結(jié)果返回
SameValue規(guī)范如下:
如果 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 的數(shù)值一致,返回 true
e. 返回 false
按照 SameValueNonNumber 的結(jié)果返回
SameValueZero這個(gè)是 eq 遵循的規(guī)范,如下:
如果 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 的數(shù)值一致,返回 true
e. 返回 false
按照 SameValueNonNumber 的結(jié)果返回
小結(jié):SameValueNonNumber 是基本,Strict Equality Comparison 、SameValue 和 SameValueZero 只是在對待 +0、-0 和 NaN 上有區(qū)別。
源碼分析來看下 eq 的源碼:
function eq(value, other) { return value === other || (value !== value && other !== other) }
其實(shí)eq 的源碼其實(shí)就只有這么一句。
既然 eq 遵循的是 SameValueZero 規(guī)范,那就將源碼來拆解一下,看它是怎樣符合規(guī)范的。
首先,看第一部分:
value === other
就是這么一段,符合的是 Strict Equality Comparison 規(guī)范,通過對比可以發(fā)現(xiàn), Strict Equality Comparison 和 SameValueZero 只在對待 NaN 上有區(qū)別。
Strict Equality Comparison 規(guī)定就算 x 和 y 都為 NaN 時(shí),返回的是 false, NaN === NaN 返回的就是 false。但是 SameValueZero 返回的是規(guī)定 x 和 y 都為 NaN 時(shí)返回的是 true。因此只需要在 Strict Equality Comparison 的基礎(chǔ)上處理 NaN 就可以了。
下面這段便是處理 NaN 的:
(value !== value && other !== other)
在 js 中,只有 NaN 和自身是不相等的,當(dāng)兩個(gè)需要比較的值都是和自身不相等時(shí),表明這兩個(gè)值都為 NaN,返回 true。
這樣便遵循了 SameValueZero 的比較實(shí)現(xiàn)。
可以用Object.is()嗎?Object.is(NaN, NaN) 返回的是 true ,所以 eq 同樣可以改成:
function eq(value, other) { return value === other || Object.is(value, other) }
Object.is 同樣是比較兩個(gè)值是否一樣,但是 Object.is(+0, -0) 返回的是 false, 它遵循是的 SameValue 規(guī)范,因此不可以直接用 Object.is 替代 eq 。
可以用isNaN()嗎?還有個(gè) isNaN 的全局方法,可以用來判斷一個(gè)值是否為 NaN。例如 isNaN(NaN) 會(huì)返回 true ,那 eq 是否可以改成以下形式呢?
function eq(value, other) { return value === other || (isNaN(value) && isNaN(other)) }
答案是:不可以!
isNaN 有一個(gè)很怪異的行為,如果傳入的參數(shù)不為 Number 類型,會(huì)嘗試轉(zhuǎn)換成 Number 類型之后再做是否為 NaN 的判斷。所以類似 isNaN("notNaN") 返回的也是 true ,因?yàn)樽址?notNaN 會(huì)先被轉(zhuǎn)換成 NaN 再做判斷,這不是我們想要的結(jié)果。
可以用Number.isNaN()嗎為了修復(fù) isNaN 的缺陷,es6 在 Number 對象上擴(kuò)展了 isNaN 方法,只有是 NaN 時(shí)才會(huì)返回 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署名-非商業(yè)性使用-禁止演繹 4.0 國際 (CC BY-NC-ND 4.0)
最后,所有文章都會(huì)同步發(fā)送到微信公眾號上,歡迎關(guān)注,歡迎提意見:
作者:對角另一面
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/90643.html
摘要:作用與用法是的內(nèi)部函數(shù),之前在源碼分析之緩存介紹過一種這樣的數(shù)據(jù)結(jié)構(gòu)這是一個(gè)二維數(shù)組,每項(xiàng)中的第一項(xiàng)作為緩存對象的,第二項(xiàng)為緩存的值。 這個(gè)世界需要一個(gè)特定的惡人,可以供人們指名道姓,千夫所指:全都怪你。——村上春樹《當(dāng)我談跑步時(shí)我談些什么》 本文為讀 lodash 源碼的第六篇,后續(xù)文章會(huì)更新到這個(gè)倉庫中,歡迎 star:pocket-lodash gitbook也會(huì)同步倉庫的更新...
摘要:依賴源碼分析之緩存使用方式的進(jìn)一步封裝源碼分析之源碼分析之源碼分析之的實(shí)現(xiàn)源碼分析之源碼分析的調(diào)用如果有傳遞,則先調(diào)用,使用生成要比較數(shù)組的映射數(shù)組。循環(huán)完畢,沒有在第二個(gè)數(shù)組中發(fā)現(xiàn)相同的項(xiàng)時(shí),將該項(xiàng)存入數(shù)組中。 外部世界那些破舊與貧困的樣子,可以使我內(nèi)心世界得到平衡。——卡爾維諾《煙云》 本文為讀 lodash 源碼的第十七篇,后續(xù)文章會(huì)更新到這個(gè)倉庫中,歡迎 star:pocke...
摘要:到這里,源碼分析完了。但是,有兩個(gè)致命的特性的遍歷不能保證順序會(huì)遍歷所有可枚舉屬性,包括繼承的屬性。的遍歷順序依賴于執(zhí)行環(huán)境,不同執(zhí)行環(huán)境的實(shí)現(xiàn)方式可能會(huì)不一樣。 小時(shí)候,鄉(xiāng)愁是一枚小小的郵票, 我在這頭, 母親在那頭。 長大后,鄉(xiāng)愁是一張窄窄的船票, 我在這頭, 新娘在那頭。 后來啊, 鄉(xiāng)愁是一方矮矮的墳?zāi)梗?我在外頭, 母親在里頭。 而現(xiàn)在, 鄉(xiāng)愁是一灣淺淺的海峽, 我在這頭, 大...
摘要:首先是通過創(chuàng)建一個(gè)函數(shù),然后向其傳遞參與計(jì)算的值,也就是說應(yīng)該是返回一個(gè)函數(shù),并且有兩個(gè)參數(shù)。事實(shí)上就是這樣,返回值是一個(gè),是被加數(shù),是加數(shù)。 源碼注釋版 這一組函數(shù)都是數(shù)學(xué)計(jì)算相關(guān)的,主要分為三類: 加減乘除:add、subtract、multiply、divide 求最大最小平均值:max、maxBy、min、minBy、sum、sumBy、mean、meanBy 小數(shù)的四舍...
摘要:今天要講的,是我從的源碼實(shí)現(xiàn)文件中學(xué)到的幾個(gè)很基礎(chǔ),卻又容易被忽略的知識點(diǎn)。在函數(shù)式編程中,函數(shù)是一等公民,它可以只是根據(jù)參數(shù),做簡單的組合操作,再作為別的函數(shù)的返回值。所以,閱讀源碼,是一種很棒的重溫基礎(chǔ)知識的方式。 showImg(https://segmentfault.com/img/bVbpTSY?w=750&h=422); 前言 上一篇文章 「前端面試題系列8」數(shù)組去重(1...
閱讀 675·2021-09-30 09:47
閱讀 2869·2021-09-04 16:40
閱讀 853·2019-08-30 13:18
閱讀 3447·2019-08-29 16:22
閱讀 1551·2019-08-29 12:36
閱讀 583·2019-08-29 11:11
閱讀 1474·2019-08-26 13:47
閱讀 1127·2019-08-26 13:32