摘要:文章起因近期因為對函數式編程的產生了濃厚的興趣然后開始了的源碼閱讀結果開開頭就看到了這樣的代碼當時看到這樣的數列一看就知道是的次方遞增跟二進制逃不了干系然后我在函數里面發現這個函數主要是由一個的函數實現然后我又進入了這個函數里面這里面有個按
文章起因
近期因為對函數式編程的curry產生了濃厚的興趣,然后開始了lodash的源碼閱讀,結果開開頭就看到了這樣的代碼
var WRAP_BIND_FLAG = 1, WRAP_BIND_KEY_FLAG = 2, WRAP_CURRY_BOUND_FLAG = 4, WRAP_CURRY_FLAG = 8, WRAP_CURRY_RIGHT_FLAG = 16, WRAP_PARTIAL_FLAG = 32, WRAP_PARTIAL_RIGHT_FLAG = 64, WRAP_ARY_FLAG = 128, WRAP_REARG_FLAG = 256, WRAP_FLIP_FLAG = 512;
當時看到2,4,8,16,這樣的數列一看就知道是2的次方遞增,跟二進制逃不了干系.
然后我在curry函數里面發現這個函數主要是由一個 createWrap的函數 實現, 然后我又進入了這個函數里面
var isBindKey = bitmask & WRAP_BIND_KEY_FLAG; bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
這里面有個按位與操作,我一看這上面的操作我都懂,但是我不知道,這些操作的結果能干嘛,也不知道為什么要這么做,于是就開始了我的求知之旅.
然后看到 lodash 作者在 那一段 標記聲明語句的上面 寫了這么一個注釋
/* Used to compose bitmasks for function metadata. /
bitmasks? 先搜一下...
bitmasks是啥寫過代碼的都知道,有些操作要判斷他是什么狀態才執行,什么狀態不執行.
那么我們就需要一些標記來幫助我們來確定,他是什么狀態的.狀態可不止 true false 有時候可以很多.
bitmasks 就是用來標記狀態的,只不過他是用位的方式來標記.
比如: 0001,可以表示一種狀態, 0011 也可以表示一種狀態.
為什么要用 bitmasks相信大家寫過這樣的代碼,比如程序員的擼碼和寫文章狀態.
var NOW_Status = 0; var CODING = 1; var WRITING = 2;
我們可以在上面的狀態中切換,我們設置狀態的時候可以這樣設置.
var NOW_STATUS = CODING; if (NOW_STATUS === CODING) { // todo }
如果我們的狀態需要組合,比如我現在一邊寫文章,一邊擼碼,那么我們是否要定義多一個狀態WRITING_CODING,來滿足我們的需求呢?
學過排列與組合的就知道,當狀態越多的時候,組合是成次方增長的. 所以我們得要把這個變成運算,不能手動的生成...
bitmarks 如何使用如果使用bitmasks 狀態就會變成下面這樣.
var NOW_Status = 0; var CODING = 2; var WRITING = 4;
那么,現在我們設置狀態還用 a = b 這種形式嗎,既然使用了 bitmarks 那就要體現出這個 bit.
現在我們這樣設置狀態
var NOW_STATUS |= CODEING
二進制就不再這里跟大家說了,程序員必備知識
這里用8位來演示,16 32 也不過是多幾個0而已
NOW_STATUS: 0 => 0000 0000
CODEING: 2 => 0000 0010
按位或操作 同位兩個數任意一個是1 結果就為1
得到 0000 0010 如此狀態設置成功
NOW_STATES === 2
| 按位或操作是放大操作, 也就得到的數可能會比兩個都大,如果前面的值是0,后面的值大于0, 那么得到的結果就是后者的本身,如此就完成了CODEING的狀態設定;
若是我們要消除這個狀態,普通做法是重新賦值為NO_STATUS,現在我們這樣做.
var NOW_STATUS &= ~(CODEING)
為什么要按位非,我們用按位或操作設置了值,如果我們要返回去,那么我們必須要按位與才能夠返回去,因為一個為放大操作,一個為縮小操作,那么我們怎么才能返回去呢,按位與操作 相同位只要有一個0 那么結果位就是0 那么簡單了 我們只要把原來放大的數的相同位的1變回0 就可以了, 在按位操作中,~ 就是這樣的操作,就像這樣
2 => 0000 0010
按位非后 1111 1101
在與 0000 0010 按位與
變成0000 0000 了,
看這就回去了;
我如何知道我在那個狀態如果兩個大于0的相同的數 按位與,結果會返回原來的數
就像這樣,
NOW_STATUS & CODEING > 0 那么就可以確定你再哪個狀態了
那么如果我的狀態要組合呢? 就是這兩個狀態隨便一個都符合要求的操作, 還需要重新定義一些狀態嗎, 不用, 我們有或操作, 這也是符合, 一真為真,同假才假的原則.像是這樣.
var NOW_STATUS= CODEING | WRITING
nor! 狀態出來了, 而且極具可讀性, 一看就知道我或者在CODEING或者在WRITING.
解釋:
2 | 4 對比 返回的是6 任何兩個不一樣的數相或 ,都不會有重復的,因此 只要你定義狀態的時候 符合 1,2,4,8,16,32 這樣的規律你就不會擔心狀態值相等;
這樣
NOW_STATUS & (CODEING | WRITING) != 0
首先NOW_STATUS 是由 CODEING | WRITING 來運算出來的, 也就是說這里兩個數是相等的... 兩個相等的值做&操作, 返回的就是值本身, 又因為NOW_STATUS 原本就是0 所以 如果他不是0, 那么就說明這個值是由這兩個狀態運算得來, 也就可以確認"我"在這個狀態組合里面了
bitmarks 的好處其實在為什么要用bitmarks 的時候 出現的都是 bitmarks 的好處
但是還有一樣, 就是性能, 我們知道內存中數字都是2進制存的, 那么我們操作數字的時候使用2進制的方式操作,能夠節省掉那么一絲的系統資源,螞蟻雖小也是肉!
最后路漫漫其修遠兮,吾將上下而求索.
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/108456.html
摘要:但是在類中,要初始化緩存和設置緩存都需要提供和組成的二維數組,因此在類中,提供了一種更方便的緩存設置方式,只需要提供緩存的值即可。這里構造函數不需要再傳入的二維數組了,只需要傳入包含所有緩存值的數組即可。 在世界上所有的民族之中,支配著他們的喜怒選擇的并不是天性,而是他們的觀點。——盧梭《社會與契約論》 本文為讀 lodash 源碼的第九篇,后續文章會更新到這個倉庫中,歡迎 star...
摘要:但是在類中,要初始化緩存和設置緩存都需要提供和組成的二維數組,因此在類中,提供了一種更方便的緩存設置方式,只需要提供緩存的值即可。這里構造函數不需要再傳入的二維數組了,只需要傳入包含所有緩存值的數組即可。 在世界上所有的民族之中,支配著他們的喜怒選擇的并不是天性,而是他們的觀點。——盧梭《社會與契約論》 本文為讀 lodash 源碼的第九篇,后續文章會更新到這個倉庫中,歡迎 star...
摘要:依賴源碼分析之緩存使用方式的進一步封裝源碼分析之源碼分析之源碼分析之的實現源碼分析之源碼分析的調用如果有傳遞,則先調用,使用生成要比較數組的映射數組。循環完畢,沒有在第二個數組中發現相同的項時,將該項存入數組中。 外部世界那些破舊與貧困的樣子,可以使我內心世界得到平衡。——卡爾維諾《煙云》 本文為讀 lodash 源碼的第十七篇,后續文章會更新到這個倉庫中,歡迎 star:pocke...
摘要:作用與用法是的內部函數,之前在源碼分析之緩存介紹過一種這樣的數據結構這是一個二維數組,每項中的第一項作為緩存對象的,第二項為緩存的值。 這個世界需要一個特定的惡人,可以供人們指名道姓,千夫所指:全都怪你。——村上春樹《當我談跑步時我談些什么》 本文為讀 lodash 源碼的第六篇,后續文章會更新到這個倉庫中,歡迎 star:pocket-lodash gitbook也會同步倉庫的更新...
摘要:卡爾維諾煙云本文為讀源碼的第二十一篇,后續文章會更新到這個倉庫中,歡迎也會同步倉庫的更新,地址依賴源碼分析之數據類型獲取的兼容性源碼分析之源碼分析用來判斷某個值是否為類對象。如果某個值為類對象使用判斷,并且調用返回的值為時,則為類對象。 有人命中注定要過平庸的生活,默默無聞,因為他們經歷了痛苦或不幸;有人卻故意這樣做,那是因為他們得到的幸福超過了他們的承受能力。——卡爾維諾《煙云》 ...
閱讀 3246·2021-11-24 09:39
閱讀 2931·2021-09-09 11:34
閱讀 3199·2021-09-07 09:58
閱讀 2305·2019-08-30 13:07
閱讀 2868·2019-08-29 15:09
閱讀 1569·2019-08-29 13:01
閱讀 2309·2019-08-26 12:18
閱讀 1927·2019-08-26 10:28