lodash原始碼分析之List快取

2022-07-03 14:42:13 字數 3748 閱讀 8954

昨日我沿著河岸/漫步到/蘆葦彎腰喝水的地方

順便請煙囪/在天空為我寫一封長長的信

潦是潦草了些/而我的心意/則明亮亦如你窗前的燭光/稍有曖昧之處/勢所難免/因為風的緣故

——洛夫《因為風的緣故》

本文為讀 lodash 原始碼的第七篇,後續文章會更新到這個倉庫中,歡迎 star:pocket-lodash

在之前的《lodash原始碼分析之hash快取》介紹過用hash做快取的情況,在這篇文章中介紹過,lodash 是想要實現和map一樣的介面。

hash其實是用物件來做快取,但是物件有乙個侷限,它的key只能是字串或者symbol型別,但是map是支援各種型別的值來作為key,因此hash快取無法完全模擬map的行為,當遇到key為陣列、物件等型別時,hash就無能為力了。

因此,在不支援map的環境下,lodash實現了listcache來模擬,listcache本質上是使用乙個二維陣列來儲存資料。

listcache的呼叫方式和hash一致:

new listcache([

[, 1],

[['an array key'],2],

[function(),3]

])

返回的結果如下:

, 1],

[['an array key'],2],

[function(),3]

]}

結構和hash類似,但是__data__變成了陣列。

listcache的介面與hash一樣,同樣實現了map的資料管理介面。

import associndexof from './associndexof.js'
《lodash原始碼分析之自減的兩種形式》

class listcache 

} clear()

delete(key)

const lastindex = data.length - 1

if (index == lastindex) else

--this.size

return true

} get(key)

has(key)

set(key, value) else

return this

}}

構造器跟hash一模一樣,都是先呼叫clear方法,然後呼叫set方法,往快取中加入初始資料。

這裡呼叫clear方法並不是說為了清除資料,還沒開始使用這個類,肯定是沒有資料的,而是為了初始化__data__size這兩個屬性。

clear()
clear是為了清空快取。

其實就是將容器__data__設定成空陣列,在hash中是設定為空物件,將快取數量size設定為0

has(key)
has用來判斷是否已經有快取資料,如果快取資料已經存在,則返回true

在之前的文章中已經介紹過,associndexof檢測的是對應key[key,value]陣列在二維陣列中的索引,其行為跟indexof一致,不存在於二維陣列中時,返回-1,否則返回索引值。因此可以用是否大於-1來判斷指定key的資料是否已經被快取。

set(key, value)  else 

return this

}

set用來增加或者更新需要快取的值。set的時候需要同時維護size和快取的值。

has一樣,呼叫associndexof找到指定key的索引值,如果小於0,則表明指定的key尚未快取,需要將快取數量size1,然後將快取資料加入到this.__data__的末尾。

否則更新value即可。

強迫症看到has用大於-1來判斷,而這裡用小於0來判斷可能會相當難受。

get(key)
get方法是從快取中取值。

如果快取中存在值,則返回快取中的值,否則返回undefined

delete(key) 

const lastindex = data.length - 1

if (index == lastindex) else

--this.size

return true

}

delete方法用來刪除指定key的快取。成功刪除返回true, 否則返回false。 刪除操作同樣需要維護size屬性。

首先呼叫associndexof來找到快取的索引。

如果索引小於0,表明沒有快取,刪除不成功,直接返回false

如果要刪除的快取是快取中的最後一項,則直接呼叫pop方法,將快取刪除,否則將呼叫splice方法將對應位置的快取刪除。

為什麼不直接都用splice來刪除資料呢?因為pop的效能比splice好,我簡單測了一下,大概快17%左右。

有興趣的可以看下popsplice的規範,splice要比pop做的事情要多。

從這裡又看出了lodash對效能的極致追求。

最後將快取數量size減少1

set 和 map 資料結構

mdn: 使用物件

ecmascript5.1中文版 + ecmascript3 + ecmascript(合集)

署名-非商業性使用-禁止演繹 4.0 國際 (cc by-nc-nd 4.0)

lodash原始碼分析之Number

一 lodash版本 4.17.5 二 函式 1 clamp 1 定義 clamp number,lower upper 2 作用 返回加緊的數字。3 例子。const require lodash console.log clamp 10,1,20 輸出 10 console.log clamp ...

lodash原始碼分析之isArguments

有人命中註定要過平庸的生活,默默無聞,因為他們經歷了痛苦或不幸 有人卻故意這樣做,那是因為他們得到的幸福超過了他們的承受能力。卡爾維諾 煙雲 本文為讀 lodash 原始碼的第二十一篇,後續文章會更新到這個倉庫中,歡迎 star pocket lodash import gettag from in...

lodash原始碼分析之快取方式的選擇

每個人心裡都有一團火,路過的人只看到煙。至愛梵谷 星空之謎 本文為讀 lodash 原始碼的第八篇,後續文章會更新到這個倉庫中,歡迎 star pocket lodash 在 lodash原始碼分析之hash快取 和 lodash原始碼分析之list快取 介紹了 lodash 的兩種快取方式,這兩種...