国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

lodash源碼分析之List緩存

SunZhaopeng / 716人閱讀

摘要:在之前的文章中已經介紹過,檢測的是對應的數組在二維數組中的索引,其行為跟一致,不存在于二維數組中時,返回,否則返回索引值。最后將緩存數量減少。

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

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

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

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

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

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

作用與用法

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

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

因此,在不支持 Map 的環境下,lodash 實現了 ListCache 來模擬,ListCache 本質上是使用一個二維數組來儲存數據。

ListCache 的調用方式和 Hash 一致:

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

返回的結果如下:

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

結構和 Hash 類似,但是 __data__ 變成了數組。

接口設計

ListCache 的接口與 Hash 一樣,同樣實現了 Map 的數據管理接口。

依賴
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

構造器跟 Hash 一模一樣,都是先調用 clear 方法,然后調用 set 方法,往緩存中加入初始數據。

這里調用 clear 方法并不是說為了清除數據,還沒開始使用這個類,肯定是沒有數據的,而是為了初始化 __data__size 這兩個屬性。

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

clear 是為了清空緩存。

其實就是將容器 __data__ 設置成空數組,在 Hash 中是設置為空對象,將緩存數量 size 設置為 0

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

has 用來判斷是否已經有緩存數據,如果緩存數據已經存在,則返回 true

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

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 的時候需要同時維護 size 和緩存的值。

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

否則更新 value 即可。

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

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。 刪除操作同樣需要維護 size 屬性。

首先調用 assocIndexOf 來找到緩存的索引。

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

如果要刪除的緩存是緩存中的最后一項,則直接調用 pop 方法,將緩存刪除,否則將調用 splice 方法將對應位置的緩存刪除。

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

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

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

最后將緩存數量 size 減少 1

參考

Set 和 Map 數據結構

MDN: 使用對象

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

License

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

最后,所有文章都會同步發送到微信公眾號上,歡迎關注,歡迎提意見:

作者:對角另一面

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92485.html

相關文章

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

    摘要:接口設計同樣實現了跟一致的數據管理接口,如下依賴源碼分析之緩存源碼分析之緩存源碼分析是否使用這個函數用來判斷是否使用緩存。返回表示使用緩存,返回則使用或者緩存。獲取對應緩存方式的實例這個函數根據來獲取儲存了該的緩存實例。 每個人心里都有一團火,路過的人只看到煙。——《至愛梵高·星空之謎》 本文為讀 lodash 源碼的第八篇,后續文章會更新到這個倉庫中,歡迎 star:pocket-...

    HitenDev 評論0 收藏0
  • lodash源碼分析緩存方式的選擇

    摘要:接口設計同樣實現了跟一致的數據管理接口,如下依賴源碼分析之緩存源碼分析之緩存源碼分析是否使用這個函數用來判斷是否使用緩存。返回表示使用緩存,返回則使用或者緩存。獲取對應緩存方式的實例這個函數根據來獲取儲存了該的緩存實例。 每個人心里都有一團火,路過的人只看到煙。——《至愛梵高·星空之謎》 本文為讀 lodash 源碼的第八篇,后續文章會更新到這個倉庫中,歡迎 star:pocket-...

    AdolphLWQ 評論0 收藏0
  • lodash源碼分析List緩存

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

    leon 評論0 收藏0
  • lodash源碼分析緩存使用方式的進一步封裝

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

    neroneroffy 評論0 收藏0
  • lodash源碼分析緩存使用方式的進一步封裝

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

    wapeyang 評論0 收藏0

發表評論

0條評論

SunZhaopeng

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<