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

資訊專欄INFORMATION COLUMN

lodash源碼分析之Hash緩存

justjavac / 2175人閱讀

摘要:只接收一個(gè)二維數(shù)組作為參數(shù),調(diào)用方式如下其中子項(xiàng)中的第一項(xiàng)會(huì)作為,第二項(xiàng)是需要緩存的值。實(shí)例化的結(jié)果如下緩存的數(shù)量?jī)?chǔ)存在的對(duì)象中。的作用是清空緩存,因此需要將重置為。將緩存的數(shù)據(jù)設(shè)置為空對(duì)象。因?yàn)樵诰彺嬷惺且詠?lái)表示的,因此遇到值為時(shí),返回。

在那小小的夢(mèng)的暖閣,我為你收藏起整個(gè)季節(jié)的煙雨。

——洛夫《靈河》

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

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

作用與用法

Hash 顧名思義,就是要有一個(gè)離散的序列,根據(jù) key 來(lái)儲(chǔ)取數(shù)據(jù)。而在 javascript 中,最適合的無(wú)疑是對(duì)象了。

Hash 在 lodash 的 .internal 文件夾中,作為內(nèi)部文件來(lái)使用。lodash 會(huì)根據(jù)不同的數(shù)據(jù)類型選擇不同的緩存方式,Hash 便是其中的一種方式,這種方式只能緩存 key 的類型符合對(duì)象鍵要求的數(shù)據(jù)。

Hash 只接收一個(gè)二維數(shù)組作為參數(shù),調(diào)用方式如下:

new Hash([["tes1", 1],["test2",2],["test3",3]])

其中子項(xiàng)中的第一項(xiàng)會(huì)作為 key ,第二項(xiàng)是需要緩存的值。

Hash 實(shí)例化的結(jié)果如下:

{
  size: 3,
  __data__: {
    test1: 1,
    test2: 2,
    test3: 3
  }
}

緩存的數(shù)量?jī)?chǔ)存在 __data__ 的對(duì)象中。

Hash與Map

后面將會(huì)講到,除了使用 Hash 方式緩存數(shù)據(jù)外,還會(huì)用到 Map,lodash 在設(shè)計(jì) Hash 的數(shù)據(jù)管理接口時(shí),也與 Map 的接口一致,但是不會(huì)包含 Map 的遍歷方法。

先來(lái)看看這些接口都有那些:

源碼
const HASH_UNDEFINED = "__lodash_hash_undefined__"

class Hash {
  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__ = Object.create(null)
    this.size = 0
  }
  delete(key) {
    const result = this.has(key) && delete this.__data__[key]
    this.size -= result ? 1 : 0
    return result
  }
  get(key) {
    const data = this.__data__
    const result = data[key]
    return result === HASH_UNDEFINED ? undefined : result
  }
  has(key) {
    const data = this.__data__
    return data[key] !== undefined
  }
  set(key, value) {
    const data = this.__data__
    this.size += this.has(key) ? 0 : 1
    data[key] = value === undefined ? HASH_UNDEFINED : value
    return this
  }
}

export default Hash
constructor
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])
    }
  }

constructor 中并沒(méi)有看到初始化 __data__ 屬性和 size 屬性,這個(gè)其實(shí)在 clear 方法中初始化了,后面會(huì)解釋。

接著遍歷傳入的二維數(shù)組,調(diào)用 set 方法,初始化緩存的值。將子項(xiàng)的第一項(xiàng)作為 key ,第二項(xiàng)為緩存的值。

clear
clear() {
  this.__data__ = Object.create(null)
  this.size = 0
}

clear 的作用是清空緩存,因此需要將 size 重置為 0。

將緩存的數(shù)據(jù) __data__ 設(shè)置為空對(duì)象。

這里并沒(méi)有用 this.__data__ = {} 置空,而是調(diào)用了 Object.create 方法,并且將 null 作為參數(shù)。我們都知道, Object.create 的第一個(gè)參數(shù)為創(chuàng)建對(duì)象的原型對(duì)象,傳入 null 的時(shí)候,返回的就是一個(gè)真空對(duì)象,即沒(méi)有原型的對(duì)象,因此不會(huì)有原型屬性的干擾,用來(lái)做緩存對(duì)象十分適合。

has
has(key) {
  const data = this.__data__
  return data[key] !== undefined
}

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

判斷也十分簡(jiǎn)單,只需要判斷取出來(lái)的值是否為 undefined 即可。

這個(gè)判斷有一個(gè)坑,后面會(huì)講到。

set
set(key, value) {
  const data = this.__data__
  this.size += this.has(key) ? 0 : 1
  data[key] = value === undefined ? HASH_UNDEFINED : value
  return this
}

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

首先調(diào)用 has 方法,判斷對(duì)應(yīng)的 key 是否已經(jīng)被緩存過(guò),如果已經(jīng)緩存過(guò),則 size 保持不變,否則 size1 。

緩存值其實(shí)就是設(shè)置緩存對(duì)象 this.__data__ 對(duì)應(yīng) key 屬性的值。

has 中說(shuō)到用 data[key] !== undefined 有一個(gè)坑,因?yàn)橐彺娴闹狄部梢允?undefined ,如果不做處理,肯定會(huì)導(dǎo)致判斷錯(cuò)誤。

lodash 的處理方式是將 undefined 的值轉(zhuǎn)換成 HASH_UNDEFINED ,也即一開(kāi)始便定義的 __lodash_hash_undefined__ 字符串來(lái)儲(chǔ)存。

所以在緩存中,是用字符串 __lodash_hash_undefined__ 來(lái)替代 undefined 的。

set 在最后還將實(shí)例 this 返回,以支持鏈?zhǔn)讲僮鳌?/p> get

get(key) {
  const data = this.__data__
  const result = data[key]
  return result === HASH_UNDEFINED ? undefined : result
}

get 方法是從緩存中取值。

取值其實(shí)就是返回緩存對(duì)象中對(duì)應(yīng) key 的值即可。因?yàn)?undefined 在緩存中是以 __lodash_hash_undefined__ 來(lái)表示的,因此遇到值為 __lodash_hash_undefined__ 時(shí),返回 undefined

其實(shí)這樣還是有小小的問(wèn)題的,如果需要緩存的值剛好是 __lodash_hash_undefined__,那取出來(lái)的值跟預(yù)設(shè)的就不一致了。但是這樣情況應(yīng)該很少出現(xiàn)吧。

delete
delete(key) {
  const result = this.has(key) && delete this.__data__[key]
  this.size -= result ? 1 : 0
  return result
}

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

首先調(diào)用 has 方法來(lái)判斷緩存是否存在,如果存在,用 delete 操作符將 __data__ 中對(duì)應(yīng)的屬性刪除。

delete 操作符在成功刪除屬性時(shí)會(huì)返回 true,如果成功刪除,則需要將 size 減少 1

參考

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

Object.create()

License

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

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

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

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

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

相關(guān)文章

  • lodash源碼分析緩存使用方式的進(jìn)一步封裝

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

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

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

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

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

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

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

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

    摘要:只接收一個(gè)二維數(shù)組作為參數(shù),調(diào)用方式如下其中子項(xiàng)中的第一項(xiàng)會(huì)作為,第二項(xiàng)是需要緩存的值。實(shí)例化的結(jié)果如下緩存的數(shù)量?jī)?chǔ)存在的對(duì)象中。的作用是清空緩存,因此需要將重置為。將緩存的數(shù)據(jù)設(shè)置為空對(duì)象。因?yàn)樵诰彺嬷惺且詠?lái)表示的,因此遇到值為時(shí),返回。 在那小小的夢(mèng)的暖閣,我為你收藏起整個(gè)季節(jié)的煙雨。——洛夫《靈河》 本文為讀 lodash 源碼的第四篇,后續(xù)文章會(huì)更新到這個(gè)倉(cāng)庫(kù)中,歡迎 sta...

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

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

0條評(píng)論

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