欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解?Map?和?WeakMap?區(qū)別以及使用場景

 更新時間:2022年01月25日 17:04:04   作者:小丞同學(xué)  
這篇文章主要介紹了詳解?Map?和?WeakMap?區(qū)別以及使用場景,Map本質(zhì)上是一個鍵值對的集合,WeakMap?只能將對象作為鍵名,下面來一起倆姐更多詳細內(nèi)容吧,希望這一篇文章能讓你對?Map?有更好的理解,或者能夠幫你理解?Map?和?WeakMap

一、為什么是 Map ?

1. 傳統(tǒng)對象結(jié)構(gòu)

Map本質(zhì)上是一個鍵值對的集合。和傳統(tǒng)對象結(jié)構(gòu)相比,傳統(tǒng)的對象只能用「字符串作為鍵名」,這就在使用上造成了很大的限制了。這也是新增 Map 的原因之一。

const data = {};
// element 為節(jié)點對象
const element = document.querySelector(".node");
console.log(element); // 輸出 div.node 對象
// 將對象轉(zhuǎn)化成字符串輸出 [object HTMLDivElement]
console.log(element.toString());?
// 用點操作符不能有空格,所以采用中括號的形式給對象賦值
data[element] = 'objectData'
// 輸出 objectData,說明在對象中存在[object HTMLDivElement]鍵名
console.log(data['[object HTMLDivElement]']);

在上面的代碼中,我們創(chuàng)建了一個對象并將一個節(jié)點對象作為了它的鍵名,并進行了代碼測試,首先驗證了獲取到的element節(jié)點為一個對象,再確定了經(jīng)過toString方法轉(zhuǎn)化后的結(jié)果,以這個值為鍵名成功的輸出了valueobjectData

通過上面的測試,確定了傳統(tǒng)對象的鍵名會通過toString方法轉(zhuǎn)化為「字符串類型」

注意:在我們訪問對象成員時,鍵名「有空格」時不能采用點訪問,例如data.ab c

這樣是「錯誤的」。我們需要采用data['ab c']的形式來訪問

2. Map 結(jié)構(gòu)

Map類似于對象,但是鍵名不限于字符串,可以說Object結(jié)構(gòu)提供鍵-值對應(yīng),Map結(jié)構(gòu)提供值-值對應(yīng)因此其實采用map結(jié)構(gòu)會優(yōu)于傳統(tǒng)對象

// 1. 通過new Map來創(chuàng)建dataMap容器
const dataMap = newMap();
// 2. 獲取節(jié)點對象,作為測試數(shù)據(jù)
const element = document.querySelector(".node");
// 3. 通過 set 方法給 dataMap 中指定鍵和對應(yīng)的值
dataMap.set(element,'objectData');
// 4. 通過 get 來從 dataMap 中獲取鍵名對應(yīng)的值
console.log(dataMap.get(element));
// 5. 揭開面目
console.log(dataMap);

從上面的代碼中,我們可以清楚的看到,第8行代碼獲取值時直接傳入了element對象,

可以成功的獲取到對應(yīng)的值,在最后打印dataMap時更是驗證了上訴說法

成功的將對象作為了鍵名,彌補了傳統(tǒng)對象的不足

3. Map 的特點

  • Map 默認情況下不包含任何鍵,所有鍵都是自己添加進去的。不同于 Object 原型鏈上有一些默認的鍵。
  • Map 的鍵可以是「任意類型」數(shù)據(jù),就連函數(shù)都可以。
  • Map 的鍵值對個數(shù)可以「輕易」通過size屬性獲取,Object 需要手動計算。
  • Map 在頻繁增刪鍵值對的場景下「性能」要比 Object 好。

4. 什么時候用 Map

要添加的鍵值名和 Object 上的默認鍵值名沖突,又不想改名時,「用 Map」
需要 String Symbol 以外的數(shù)據(jù)類型做鍵值時,「用 Map」
鍵值對很多,有需要計算數(shù)量時,「用 Map」
需要頻繁增刪鍵值對時,「用 Map」

二、Map 實例屬性和方法

在上面我們已經(jīng)接觸到了Map的個別  API,接下來簡單說說

1. set

set方法設(shè)置鍵名key對應(yīng)的鍵值為value,然后會返回整個Map結(jié)構(gòu),如果設(shè)置的key已經(jīng)存在,則會更新value值,否則會新生成該鍵

2. get

通過get方法讀取key對應(yīng)的鍵值,如果傳入的鍵值不存在,則會返回undefined

控制臺成功輸出ljc

3. has

判斷傳入的鍵是否存在當前Map對象中,該方法返回一個布爾值

在上面的代碼中,存在nametrue,不存在sex返回false

4. delete

刪除傳入的鍵,返回true,如果刪除失敗,則返回false

5. clear

三、遍歷方法

可以采用for...of循環(huán)和forEach兩種方法。由于Map實例會維護鍵值對的插入順序,因此可以根據(jù)插入順序進行遍歷

采用「for...of」

for...of可以遍歷有iterator接口的數(shù)據(jù)結(jié)構(gòu)

  • keys():返回鍵名的遍歷器
  • values():返回鍵值的遍歷器
  • entries():返回鍵值對的遍歷器
  • forEach():使用回調(diào)函數(shù)遍歷每個成員

map.entries()

在Map實例中「有一個迭代器」,能以插入順序生成[key,value]形式的數(shù)據(jù)。

也可以采用如下進行遍歷,每次item獲取到一個數(shù)組

通過回調(diào)的方式遍歷map

四、Map 類型轉(zhuǎn)化

幾種與map相互類型轉(zhuǎn)化的方法

Map 轉(zhuǎn)為數(shù)組

通過擴展運算符實現(xiàn)

let map = newMap()
let arr = [...map]

數(shù)組轉(zhuǎn)為 Map
 

let map = newMap(arr)

Map 轉(zhuǎn)為對象

通過遍歷利用set將鍵值對加入對象中

let obj = {}
for (let [k, v] of map) {
? obj[k] = v
}
對象轉(zhuǎn)為 Map
for( let k ofObject.keys(obj)){
? map.set(k,obj[k])
}

五、什么是 WeakMap ?

總所周知,WeakMap是 ES6 中新增的一種集合類型,叫做“弱映射”。它和Map是兄弟關(guān)系,與Map的區(qū)別就在于這個「弱字」,API 還是Map的那套(只有set get has delete)

那它真正是什么意思呢?

這其實描述的是 JS 中「垃圾回收」程序?qū)Υ?ldquo;弱映射”中鍵的方式

那為什么要有 WeakMap 呢?它解決了什么問題呢?這些問題后面都會講到

六、WeakMap 的特性

我們先從 WeakMap 的特性講起

1. WeakMap 只能將對象作為鍵名

只接受對象作為鍵名(null 除外),不接受其他類型的值作為鍵名
「null 除外」

2. WeakMap 的鍵名引用的對象是弱引用

這里懵了挺久的,但是這是WeakMap結(jié)構(gòu)的關(guān)鍵所在

要想讀懂這句話,不容易,我們需要先知道「強引用和弱引用」

2.1 什么是強引用?

我們先來看看「強引用」,這是阮一峰老師書上的例子

「麻煩的操作勢必會造成問題,當忘記了手動刪除引用,就會造成內(nèi)存泄漏」

2.2 什么是弱引用?

對于「弱引用」,百度百科給出的答案:

在計算機程序設(shè)計中,弱引用與強引用相對,是指不能確保其引用的對象不會被垃圾回收器回收的引用。一個對象若只被弱引用所引用,則被認為是不可訪問(或弱可訪問)的,并因此可能在任何時刻被回收。

也就是說「如果」我們能這樣創(chuàng)建一個弱引用的對象

//假設(shè)
let obj = new WeakObject()

我們就可以靜靜的等待垃圾車來把它拖走了,obj所引用的對象就會被回收

如果還沒有理解的話,我們再來看看

2.3 弱引用和強引用圖解

從1套代碼結(jié)合兩張圖來理解

對于強引用:

const myMap = newMap()
let my = {
? ? name: "ljc",
? ? sex: "男"
}
myMap.set(my, 'info');
console.log(myMap);

對于弱引用

const myMap = newWeakMap()
let my = {
? ? name: "ljc",
? ? sex: "男"
}
myMap.set(my, 'info');
console.log(myMap);

圖一中的數(shù)據(jù)被my和myMap實例對象所引用,引用計數(shù)為 2,圖2中建立了myMap對my所引用的對象的「弱引用」,引用計數(shù)為 1

在上面我們談到強引用數(shù)據(jù)被刪除時,需要手動解除引用,而弱引用則可以等待垃圾回收機制自動清除

「弱引用與垃圾回收」

當執(zhí)行my = null時會解除my對原數(shù)據(jù)的引用,而myMap實例對象對my所引用對象是弱引用關(guān)系,該數(shù)據(jù)的「引用計數(shù)為 0」 ,程序垃圾回收機制在執(zhí)行時會將引用對象回收。而如果時強引用關(guān)系則「引用計數(shù)為 1」 ,不會被垃圾回收機制清除。

總的來說, WeakMap 保持了對鍵名所引用的對象的弱引用,即垃圾回收機制不將該引用考慮在內(nèi)。只要所引用的對象的其他引用都被清除,垃圾回收機制就會釋放該對象所占用的內(nèi)存。也就是說,一旦不再需要,WeakMap 里面的鍵名對象和所對應(yīng)的鍵值對會自動消失,不用手動刪除引用。

3. 不可遍歷

正因為WeakMap對鍵名所引用的對象是弱引用關(guān)系,因此WeakMap內(nèi)部成員是會「卻決于垃圾回收機制有沒有執(zhí)行」,運行前后成員個數(shù)很可能是不一樣的,而垃圾回收機制的執(zhí)行又是「不可預(yù)測」的,因此不可遍歷

了解了WeakMap的特性,相信對“為什么要有WeakMap?”已經(jīng)有了一定的答案

七、Map 和 WeakMap 的區(qū)別

看到這里相信心中已經(jīng)有答案了

  • Map 的鍵可以是任意類型,WeakMap 只接受對象作為鍵(null除外),不接受其他類型的值作為鍵
  • Map 的鍵實際上是跟內(nèi)存地址綁定的,只要內(nèi)存地址不一樣,就視為兩個鍵;WeakMap 的鍵是弱引用,鍵所指向的對象可以被垃圾回收,此時鍵是無效的
  • Map 可以被遍歷, WeakMap 不能被遍歷

八、WeakMap 的使用場景

1. DOM 節(jié)點元數(shù)據(jù)

用紅寶書的例子

因此可以采用WeakMap當節(jié)點刪除后,引用計數(shù)為0,等待垃圾回收機制回收

2. 部署私有屬性

利用弱映射,將內(nèi)部屬性設(shè)置為實例的弱引用對象,當實例刪除時,私有屬性也會隨之消失,因此不會內(nèi)存泄漏

阮一峰老師的代碼實例

3. 數(shù)據(jù)緩存

當我們需要在不修改原有對象的情況下儲存某些屬性等,而又不想管理這些數(shù)據(jù)時,可以使用WeakMap

到此這篇關(guān)于詳解 Map 和 WeakMap 區(qū)別以及使用場景的文章就介紹到這了,更多相關(guān)Map 和 WeakMap 區(qū)別以及使用場景內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!到此這篇關(guān)于詳解 Map 和 WeakMap 區(qū)別以及使用場景的文章就介紹到這了,更多相關(guān)Map 和 WeakMap 區(qū)別以及使用場景內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 腳本收藏iframe

    腳本收藏iframe

    腳本收藏iframe...
    2006-07-07
  • js獲取域名的方法

    js獲取域名的方法

    這篇文章主要介紹了js獲取域名的方法,涉及window.location中常見方法的使用技巧,需要的朋友可以參考下
    2015-01-01
  • 原生JavaScript寫出Tabs標簽頁的實例代碼

    原生JavaScript寫出Tabs標簽頁的實例代碼

    這篇文章主要介紹了原生JavaScript寫出Tabs標簽頁的實例代碼,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • textbox右鍵菜單

    textbox右鍵菜單

    textbox右鍵菜單...
    2006-10-10
  • 簡單談?wù)凧S中的正則表達式

    簡單談?wù)凧S中的正則表達式

    下面小編就為大家?guī)硪黄唵握務(wù)凧S中的正則表達式。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • webpack2.0搭建前端項目的教程詳解

    webpack2.0搭建前端項目的教程詳解

    這篇文章主要給大家介紹了關(guān)于webpack2.0搭建前端項目的相關(guān)資料,文中介紹的非常詳細,對大家學(xué)習或者使用webpack2.0具有一定的參考學(xué)習價值,需要的朋友們下面來一起看看吧。
    2017-04-04
  • JS對象和字符串之間互換操作實例分析

    JS對象和字符串之間互換操作實例分析

    這篇文章主要介紹了JS對象和字符串之間互換操作,結(jié)合實例形式分析了javascript對象與字符串相互轉(zhuǎn)換的原理與相關(guān)操作技巧,需要的朋友可以參考下
    2019-02-02
  • 移動端js觸摸事件詳解

    移動端js觸摸事件詳解

    這篇文章主要為大家詳細介紹了移動端js觸摸事件,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • 利用JavaScript實現(xiàn)網(wǎng)頁版2048小游戲

    利用JavaScript實現(xiàn)網(wǎng)頁版2048小游戲

    這篇文章主要介紹了如何利用HTML+CSS+JS編寫一個網(wǎng)頁版的2048小游戲,代碼簡單易懂對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-11-11
  • 在Postman的腳本中如何使用pm對象獲取接口的請求參數(shù)

    在Postman的腳本中如何使用pm對象獲取接口的請求參數(shù)

    這篇文章主要介紹了在Postman的腳本中如何使用pm對象獲取接口的請求參數(shù),本文通過實例代碼圖文相結(jié)合給大家介紹的非常詳細,需要的朋友可以參考下
    2023-09-09

最新評論