近期由於函數式編程的curry開始了lodash的源碼閱讀,結果開開頭就看到了這樣的代碼javascript
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,這樣的數列一看就知道是什麼東西.前端
而後我在curry函數裏面發現這個函數主要是由一個 createWrap的函數 實現, 而後我又進入了這個函數,發現裏面有這麼些代碼java
var isBindKey = bitmask & WRAP_BIND_KEY_FLAG; bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG);
這裏面有個按位與操做,如果沒學過其餘語言,直接上手javascript 的程序員 估計 會不知道這些基礎知識,我是java轉的前端,雖然java學得不怎麼樣,可是這些東西我一看就知道是什麼,可是我不知道,這些操做在幹什麼,也不知道爲何要這麼作,因而就開始了個人求知之旅.程序員
lodash 做者在 那一段 標記聲明語句的上面 寫了這麼一個註釋 編程
/* Used to compose bitmasks for function metadata. /函數式編程
bitmasks 對我來講但是一個新詞.....函數
程序猿都知道,有些操做要判斷他是什麼狀態才執行,什麼狀態不執行.性能
那麼咱們就須要一些標記來幫助咱們來肯定,他是什麼狀態的.狀態可不止 true false 這麼簡單.google
bitmasks 就是用來標記狀態的,只不過他是用位操做的方式來標記.code
相信你們寫過這樣的狀態,好比程序員的擼碼和寫文章狀態.
var NO_Status = 0; var CODING = 1; var WRITING = 2;
咱們能夠在上面的狀態中切換,咱們設置狀態的時候能夠這樣設置.
var NOW_STATUS = CODING; if (NOW_STATUS === CODING) { // todo }
當咱們要清楚狀態的時候 咱們又要從新取消狀態;
若是咱們的狀態須要組合,好比我如今一邊寫文章,一邊擼碼,那麼咱們是否要定義多一個狀態,來知足咱們的需求呢?
學過排列與組合的就知道,當狀態越多的時候,組合是成次方增加的.(意思就是,定義到你撲街---手抽筋)
若是使用bitmasks 狀態就會變成下面這樣,參考 lodash 源碼
var NO_Status = 0; var CODING = 2; var WRITING = 4;
那麼,如今咱們設置狀態還用 a = b 這種形式嗎,既然使用了 bitmarks 那就要體現出這個 bit 呀
如今咱們這樣設置狀態
var NOW_STATUS |= CODEING
二進制就再也不這裏跟你們說了,程序員必備知識
這裏用8位來演示,16 32 也不過是多幾個0而已
NOW_STATUS: 0000 0000
CODEING: 0000 0010
按位或操做 同位兩個數任意一個是1 結果就爲1
獲得 0000 0010 如此狀態設置成功
| 按位或操做是放大操做, 也就獲得的數會比兩個都大,若是前面的值是0,後面的值大於0, 那麼獲得的結果就是後者的自己,如此就設置了CODEING的 狀態 可用於 爲true 時執行的判斷;
如果咱們要消除這個狀態,普通作法是從新賦值爲NO_STATUS,如今咱們這樣作.
var NOW_STATUS &= ~(CODEING)
與是縮小操做,把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
嗯哼? OJBK
解釋: 對應上面代碼 6 & (2 | 4) != 0
6 & 4 = 4, 6 & 2 = 2, 都大於0 看判斷成功;
其實在爲何要用bitmarks 的時候 出現的都是 bitmarks 的好處
可是還有同樣, 就是性能, 咱們知道內存中數字都是2進制存的, 那麼咱們操做數字的時候使用2進制的方式操做,可以節省掉那麼一絲的系統資源,螞蟻雖小也是肉呀
lodash 真是個好東西, 雖然我不怎麼用,可是裏面的基礎和思想,是我想要的東西.
我會繼續閱讀,有我能駕馭的,必定再寫一些東西分享出來.
google 搜索 : bitmarks 前3個 哈哈哈哈哈哈哈哈哈