溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

淺談es6 javascript的map數(shù)據(jù)結(jié)構(gòu)

發(fā)布時間:2020-10-22 05:44:16 來源:腳本之家 閱讀:167 作者:專注前端30年 欄目:web開發(fā)

本文介紹了es6 javascript的map數(shù)據(jù)結(jié)構(gòu),分享給大家,具體如下:

Map 結(jié)構(gòu)的目的和基本用法

JavaScript 的對象( Object), 本質(zhì)上是鍵值對的集合( Hash 結(jié)構(gòu)), 但是傳統(tǒng)上只能用字符串當作鍵。 這給它的使用帶來了很大的限制。

var data = {}; 
var element = document.getElementById('myDiv'); 
data[element] = 'metadata'; 
data['[object HTMLDivElement]'] // "metadata" 

上面代碼原意是將一個 DOM 節(jié)點作為對象data的鍵, 但是由于對象只接受字符串作為鍵名, 所以element被自動轉(zhuǎn)為字符串[object HTMLDivElement]。

為了解決這個問題, ES6 提供了 Map 數(shù)據(jù)結(jié)構(gòu)。 它類似于對象, 也是鍵值對的集合, 但是“ 鍵” 的范圍不限于字符串, 各種類型的值( 包括對象) 都可以當作鍵。 也就是說, Object 結(jié)構(gòu)提供了“ 字符串— 值” 的對應(yīng), Map 結(jié)構(gòu)提供了“ 值— 值” 的對應(yīng), 是一種更完善的 Hash 結(jié)構(gòu)實現(xiàn)。 如果你需要“ 鍵值對” 的數(shù)據(jù)結(jié)構(gòu), Map 比 Object 更合適。

var m = new Map(); 
var o = { 
 p: 'Hello World' 
}; 
m.set(o, 'content') 
m.get(o) // "content" 
m.has(o) // true 
m.delete(o) // true 
m.has(o) // false 

上面代碼使用set方法, 將對象o當作m的一個鍵, 然后又使用get方法讀取這個鍵, 接著使用delete方法刪除了這個鍵。
作為構(gòu)造函數(shù), Map 也可以接受一個數(shù)組作為參數(shù)。 該數(shù)組的成員是一個個表示鍵值對的數(shù)組。

var map = new Map([ 
 ['name', ' 張三 '], 
 ['title', 'Author'] 
]); 
map.size // 2 
map.has('name') // true 
map.get('name') // " 張三 " 
map.has('title') // true 
map.get('title') // "Author" 

上面代碼在新建 Map 實例時, 就指定了兩個鍵name和title。

Map 構(gòu)造函數(shù)接受數(shù)組作為參數(shù), 實際上執(zhí)行的是下面的算法。

var items = [ 
 ['name', ' 張三 '], 
 ['title', 'Author'] 
]; 
var map = new Map(); 
items.forEach(([key, value]) => map.set(key, value)); 

下面的例子中, 字符串true和布爾值true是兩個不同的鍵。

var m = new Map([ 
 [true, 'foo'], 
 ['true', 'bar'] 
]); 
m.get(true) // 'foo' 
m.get('true') // 'bar' 

如果對同一個鍵多次賦值, 后面的值將覆蓋前面的值。

let map = new Map(); 
map 
 .set(1, 'aaa') 
 .set(1, 'bbb'); 
map.get(1) // "bbb" 

上面代碼對鍵1連續(xù)賦值兩次, 后一次的值覆蓋前一次的值。

如果讀取一個未知的鍵, 則返回undefined。

new Map().get('asfddfsasadf') 
 // undefined 

注意, 只有對同一個對象的引用, Map 結(jié)構(gòu)才將其視為同一個鍵。 這一點要非常小心。

var map = new Map(); 
map.set(['a'], 555); 
map.get(['a']) // undefined 

上面代碼的set和get方法, 表面是針對同一個鍵, 但實際上這是兩個值, 內(nèi)存地址是不一樣的, 因此get方法無法讀取該鍵, 返回undefined。

同理, 同樣的值的兩個實例, 在 Map 結(jié)構(gòu)中被視為兩個鍵。

var map = new Map(); 
var k1 = ['a']; 
var k2 = ['a']; 
map 
 .set(k1, 111) 
 .set(k2, 222); 
map.get(k1) // 111 
map.get(k2) // 222 

上面代碼中, 變量k1和k2的值是一樣的, 但是它們在 Map 結(jié)構(gòu)中被視為兩個鍵。

由上可知, Map 的鍵實際上是跟內(nèi)存地址綁定的, 只要內(nèi)存地址不一樣, 就視為兩個鍵。 這就解決了同名屬性碰撞( clash) 的問題, 我們擴展別人的庫的時候, 如果使用對象作為鍵名, 就不用擔心自己的屬性與原作者的屬性同名。

如果 Map 的鍵是一個簡單類型的值( 數(shù)字、 字符串、 布爾值), 則只要兩個值嚴格相等, Map 將其視為一個鍵, 包括0和 - 0。 另外, 雖然NaN不嚴格相等于自身, 但 Map 將其視為同一個鍵。

let map = new Map(); 
map.set(NaN, 123); 
map.get(NaN) // 123 
map.set(-0, 123); 
map.get(+0) // 123 

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI