成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

lodash源碼分析之List緩存

leon / 2093人閱讀

摘要:在之前的文章中已經(jīng)介紹過,檢測(cè)的是對(duì)應(yīng)的數(shù)組在二維數(shù)組中的索引,其行為跟一致,不存在于二維數(shù)組中時(shí),返回,否則返回索引值。最后將緩存數(shù)量減少。

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

順便請(qǐng)煙囪/在天空為我寫一封長(zhǎng)長(zhǎng)的信

潦是潦草了些/而我的心意/則明亮亦如你窗前的燭光/稍有曖昧之處/勢(shì)所難免/因?yàn)轱L(fēng)的緣故

——洛夫《因?yàn)轱L(fēng)的緣故》

本文為讀 lodash 源碼的第七篇,后續(xù)文章會(huì)更新到這個(gè)倉庫中,歡迎 star:pocket-lodash

gitbook也會(huì)同步倉庫的更新,gitbook地址:pocket-lodash

作用與用法

在之前的《lodash源碼分析之Hash緩存》介紹過用 Hash 做緩存的情況,在這篇文章中介紹過,lodash 是想要實(shí)現(xiàn)和 Map 一樣的接口。

Hash 其實(shí)是用對(duì)象來做緩存,但是對(duì)象有一個(gè)局限,它的 key 只能是字符串或者 Symbol 類型,但是 Map 是支持各種類型的值來作為 key,因此 Hash 緩存無法完全模擬 Map 的行為,當(dāng)遇到 key 為數(shù)組、對(duì)象等類型時(shí),Hash 就無能為力了。

因此,在不支持 Map 的環(huán)境下,lodash 實(shí)現(xiàn)了 ListCache 來模擬,ListCache 本質(zhì)上是使用一個(gè)二維數(shù)組來儲(chǔ)存數(shù)據(jù)。

ListCache 的調(diào)用方式和 Hash 一致:

new ListCache([
  [{key: "An Object Key"}, 1],
  [["An Array Key"],2],
  [function(){console.log("A Function Key")},3]
])

返回的結(jié)果如下:

{
  size: 3,
  __data__: [
    [{key: "An Object Key"}, 1],
    [["An Array Key"],2],
    [function(){console.log("A Function Key")},3]
  ]
}

結(jié)構(gòu)和 Hash 類似,但是 __data__ 變成了數(shù)組。

接口設(shè)計(jì)

ListCache 的接口與 Hash 一樣,同樣實(shí)現(xiàn)了 Map 的數(shù)據(jù)管理接口。

依賴
import assocIndexOf from "./assocIndexOf.js"

《lodash源碼分析之自減的兩種形式》

源碼分析
class ListCache {

  constructor(entries) {
    let index = -1
    const length = entries == null ? 0 : entries.length

    this.clear()
    while (++index < length) {
      const entry = entries[index]
      this.set(entry[0], entry[1])
    }
  }

  clear() {
    this.__data__ = []
    this.size = 0
  }

  delete(key) {
    const data = this.__data__
    const index = assocIndexOf(data, key)

    if (index < 0) {
      return false
    }
    const lastIndex = data.length - 1
    if (index == lastIndex) {
      data.pop()
    } else {
      data.splice(index, 1)
    }
    --this.size
    return true
  }

  get(key) {
    const data = this.__data__
    const index = assocIndexOf(data, key)
    return index < 0 ? undefined : data[index][1]
  }

  has(key) {
    return assocIndexOf(this.__data__, key) > -1
  }

  set(key, value) {
    const data = this.__data__
    const index = assocIndexOf(data, key)

    if (index < 0) {
      ++this.size
      data.push([key, value])
    } else {
      data[index][1] = value
    }
    return this
  }
}
constructor

構(gòu)造器跟 Hash 一模一樣,都是先調(diào)用 clear 方法,然后調(diào)用 set 方法,往緩存中加入初始數(shù)據(jù)。

這里調(diào)用 clear 方法并不是說為了清除數(shù)據(jù),還沒開始使用這個(gè)類,肯定是沒有數(shù)據(jù)的,而是為了初始化 __data__size 這兩個(gè)屬性。

clear
clear() {
  this.__data__ = []
  this.size = 0
}

clear 是為了清空緩存。

其實(shí)就是將容器 __data__ 設(shè)置成空數(shù)組,在 Hash 中是設(shè)置為空對(duì)象,將緩存數(shù)量 size 設(shè)置為 0 。

has
has(key) {
  return assocIndexOf(this.__data__, key) > -1
}

has 用來判斷是否已經(jīng)有緩存數(shù)據(jù),如果緩存數(shù)據(jù)已經(jīng)存在,則返回 true

在之前的文章中已經(jīng)介紹過,assocIndexOf 檢測(cè)的是對(duì)應(yīng) key[key,value] 數(shù)組在二維數(shù)組中的索引,其行為跟 indexOf 一致,不存在于二維數(shù)組中時(shí),返回 -1 ,否則返回索引值。因此可以用是否大于 -1 來判斷指定 key 的數(shù)據(jù)是否已經(jīng)被緩存。

set
set(key, value) {
  const data = this.__data__
  const index = assocIndexOf(data, key)

  if (index < 0) {
    ++this.size
    data.push([key, value])
  } else {
    data[index][1] = value
  }
  return this
}

set 用來增加或者更新需要緩存的值。set 的時(shí)候需要同時(shí)維護(hù) size 和緩存的值。

has 一樣,調(diào)用 assocIndexOf 找到指定 key 的索引值,如果小于 0 ,則表明指定的 key 尚未緩存,需要將緩存數(shù)量 size1 ,然后將緩存數(shù)據(jù)加入到 this.__data__ 的末尾。

否則更新 value 即可。

強(qiáng)迫癥看到 has 用大于 -1 來判斷,而這里用小于 0 來判斷可能會(huì)相當(dāng)難受。

get
get(key) {
  const data = this.__data__
  const index = assocIndexOf(data, key)
  return index < 0 ? undefined : data[index][1]
}

get 方法是從緩存中取值。

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

delete
delete(key) {
  const data = this.__data__
  const index = assocIndexOf(data, key)

  if (index < 0) {
    return false
  }
  const lastIndex = data.length - 1
  if (index == lastIndex) {
    data.pop()
  } else {
    data.splice(index, 1)
  }
  --this.size
  return true
}

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

首先調(diào)用 assocIndexOf 來找到緩存的索引。

如果索引小于 0 ,表明沒有緩存,刪除不成功,直接返回 false 。

如果要?jiǎng)h除的緩存是緩存中的最后一項(xiàng),則直接調(diào)用 pop 方法,將緩存刪除,否則將調(diào)用 splice 方法將對(duì)應(yīng)位置的緩存刪除。

為什么不直接都用 splice 來刪除數(shù)據(jù)呢?因?yàn)?pop 的性能比 splice 好,我簡(jiǎn)單測(cè)了一下,大概快 17% 左右。

有興趣的可以看下 popsplice 的規(guī)范,splice 要比 pop 做的事情要多。

從這里又看出了 lodash 對(duì)性能的極致追求。

最后將緩存數(shù)量 size 減少 1 。

參考

Set 和 Map 數(shù)據(jù)結(jié)構(gòu)

MDN: 使用對(duì)象

ECMAScript5.1中文版 + ECMAScript3 + ECMAScript(合集)

License

署名-非商業(yè)性使用-禁止演繹 4.0 國(guó)際 (CC BY-NC-ND 4.0)

最后,所有文章都會(huì)同步發(fā)送到微信公眾號(hào)上,歡迎關(guān)注,歡迎提意見:

作者:對(duì)角另一面

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/61926.html

相關(guān)文章

  • lodash源碼分析緩存方式的選擇

    摘要:接口設(shè)計(jì)同樣實(shí)現(xiàn)了跟一致的數(shù)據(jù)管理接口,如下依賴源碼分析之緩存源碼分析之緩存源碼分析是否使用這個(gè)函數(shù)用來判斷是否使用緩存。返回表示使用緩存,返回則使用或者緩存。獲取對(duì)應(yīng)緩存方式的實(shí)例這個(gè)函數(shù)根據(jù)來獲取儲(chǔ)存了該的緩存實(shí)例。 每個(gè)人心里都有一團(tuán)火,路過的人只看到煙?!吨翋坭蟾摺ば强罩i》 本文為讀 lodash 源碼的第八篇,后續(xù)文章會(huì)更新到這個(gè)倉庫中,歡迎 star:pocket-...

    HitenDev 評(píng)論0 收藏0
  • lodash源碼分析緩存方式的選擇

    摘要:接口設(shè)計(jì)同樣實(shí)現(xiàn)了跟一致的數(shù)據(jù)管理接口,如下依賴源碼分析之緩存源碼分析之緩存源碼分析是否使用這個(gè)函數(shù)用來判斷是否使用緩存。返回表示使用緩存,返回則使用或者緩存。獲取對(duì)應(yīng)緩存方式的實(shí)例這個(gè)函數(shù)根據(jù)來獲取儲(chǔ)存了該的緩存實(shí)例。 每個(gè)人心里都有一團(tuán)火,路過的人只看到煙?!吨翋坭蟾摺ば强罩i》 本文為讀 lodash 源碼的第八篇,后續(xù)文章會(huì)更新到這個(gè)倉庫中,歡迎 star:pocket-...

    AdolphLWQ 評(píng)論0 收藏0
  • lodash源碼分析List緩存

    摘要:在之前的文章中已經(jīng)介紹過,檢測(cè)的是對(duì)應(yīng)的數(shù)組在二維數(shù)組中的索引,其行為跟一致,不存在于二維數(shù)組中時(shí),返回,否則返回索引值。最后將緩存數(shù)量減少。 昨日我沿著河岸/漫步到/蘆葦彎腰喝水的地方順便請(qǐng)煙囪/在天空為我寫一封長(zhǎng)長(zhǎng)的信 潦是潦草了些/而我的心意/則明亮亦如你窗前的燭光/稍有曖昧之處/勢(shì)所難免/因?yàn)轱L(fēng)的緣故 ——洛夫《因?yàn)轱L(fēng)的緣故》 本文為讀 lodash 源碼的第七篇,后續(xù)文章會(huì)...

    SunZhaopeng 評(píng)論0 收藏0
  • lodash源碼分析緩存使用方式的進(jìn)一步封裝

    摘要:但是在類中,要初始化緩存和設(shè)置緩存都需要提供和組成的二維數(shù)組,因此在類中,提供了一種更方便的緩存設(shè)置方式,只需要提供緩存的值即可。這里構(gòu)造函數(shù)不需要再傳入的二維數(shù)組了,只需要傳入包含所有緩存值的數(shù)組即可。 在世界上所有的民族之中,支配著他們的喜怒選擇的并不是天性,而是他們的觀點(diǎn)?!R梭《社會(huì)與契約論》 本文為讀 lodash 源碼的第九篇,后續(xù)文章會(huì)更新到這個(gè)倉庫中,歡迎 star...

    neroneroffy 評(píng)論0 收藏0
  • lodash源碼分析緩存使用方式的進(jìn)一步封裝

    摘要:但是在類中,要初始化緩存和設(shè)置緩存都需要提供和組成的二維數(shù)組,因此在類中,提供了一種更方便的緩存設(shè)置方式,只需要提供緩存的值即可。這里構(gòu)造函數(shù)不需要再傳入的二維數(shù)組了,只需要傳入包含所有緩存值的數(shù)組即可。 在世界上所有的民族之中,支配著他們的喜怒選擇的并不是天性,而是他們的觀點(diǎn)。——盧梭《社會(huì)與契約論》 本文為讀 lodash 源碼的第九篇,后續(xù)文章會(huì)更新到這個(gè)倉庫中,歡迎 star...

    wapeyang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<