為什要使用新的Map Set, 以及一些Map Set的資料

為什要使用新的Map Set

在沒有 Map, Set 這兩個(gè)數(shù)據(jù)類型之前盾碗, javascript 本身就可以簡單實(shí)現(xiàn)類似哈希表的東西: 基礎(chǔ)的類型-對象(Object)
一個(gè)普通的對象本身就是一個(gè) 開放的鍵值對集合乐疆,可以進(jìn)行獲取牺丙、設(shè)置、刪除蕾额、遍歷--任何一個(gè)哈希表支持的操作糊闽,那么為什么要es6 要出新的Map Set數(shù)據(jù)結(jié)構(gòu)類型呢?

  • 作為查詢表使用的對象虏冻,不能既支持方法又保證避免沖突。
  • 因?yàn)橐吹糜?code>Object.create(null)而非直接寫{}弹囚,要么得小心地避免把Object.prototype.toString之類的內(nèi)置方法名作為鍵名來存儲(chǔ)數(shù)據(jù)。
  • 對象的鍵總是字符串(es6中也可以是Symbol)而不能是另一個(gè)對象领曼。
  • 沒有郵箱的獲取屬性個(gè)數(shù)的方法鸥鹉。
  • ES6中又出現(xiàn)了新問題:純粹的對象不可遍歷,也就是庶骄,它們不能配合for-of循環(huán)或...操作符等語法毁渗。

雖然在一般的情況下,直接使用對象是很方便单刁,直接的并且正確的選擇灸异,但是ES6中的集合本來就是為避免用戶數(shù)據(jù)與內(nèi)置方法沖突而設(shè)計(jì)的,不會(huì)將數(shù)據(jù)作為屬性暴露出來。也就是說肺樟,obj.keyobj[key]不能在用來訪問數(shù)據(jù)了檐春,取而代之的是 map.get(key),并且不能通過原型鏈來繼承其他屬性么伯。

MapSet 的鍵都可以是對象疟暖,這一點(diǎn)和傳統(tǒng)的 Object 很不一樣

set: 無序不重復(fù)值的列表

一個(gè)Set不會(huì)包含相同元素。試圖再次加入一個(gè)已有元素不會(huì)產(chǎn)生任何效果

包含的操作

  • new Set:創(chuàng)建一個(gè)新的田柔、空的Set俐巴。
  • new Set(iterable):從任何可遍歷數(shù)據(jù)中提取元素,構(gòu)造出一個(gè)新的集合硬爆。
  • set.size:獲取集合的大小欣舵,即其中元素的個(gè)數(shù)。
  • set.has(value):判定集合中是否含有指定元素缀磕,返回一個(gè)布爾值缘圈。
  • set.add(value):添加元素。如果與已有重復(fù)虐骑,則不產(chǎn)生效果准验。
  • set.delete(value):刪除元素。如果并不存在廷没,則不產(chǎn)生效果糊饱。.add().delete()都會(huì)返回集合自身,所以我們可以用鏈?zhǔn)秸Z法颠黎。
  • set[Symbol.iterator]():返回一個(gè)新的遍歷整個(gè)集合的迭代器另锋。一般這個(gè)方法不會(huì)被直接調(diào)用,因?yàn)閷?shí)際上就是它使集合能夠被遍歷狭归,也就是說夭坪,我們可以直接寫for (v of set) {...}等等。
  • set.forEach(f):直接用代碼來解釋好了过椎,它就像是for (let value of set) { f(value, value, set); }的簡寫室梅,類似于數(shù)組的.forEach()方法。
  • set.clear():清空集合疚宇。
  • set.keys()亡鼠、set.values()set.entries()返回各種迭代器,它們是為了兼容Map而提供的敷待,所以我們待會(huì)兒再來看间涵。

注意

在 Set 內(nèi)部 NaN 類型的值是相等的(實(shí)際上 NaN 不等于任何值),不能傳兩個(gè) NaN 的值

let set = new Set();
let a = NaN;
let b = NaN;
set.add(a);
set.add(b);
set // Set {NaN}

上面代碼向 Set 實(shí)例添加了兩個(gè)NaN榜揖,但是只能加入一個(gè)勾哩。這表明抗蠢,在 Set 內(nèi)部,兩個(gè)NaN是相等思劳。

map:無序鍵不重復(fù)鍵值對

一個(gè) Map 不會(huì)包含相同的 鍵所構(gòu)成的鍵值對迅矛,試圖再次加入一個(gè)已存在的鍵的元素會(huì)覆蓋前者。
如果讀取一個(gè)未知的鍵敢艰,則返回undefined诬乞。

包含的操作

  • new Map:返回一個(gè)新的、空的Map钠导。
  • new Map(pairs):根據(jù)所含元素形如[key, value]的數(shù)組 pairs 來創(chuàng)建一個(gè)新的 Map震嫉。這里提供的pairs可以是一個(gè)已有的Map 對象,可以是一個(gè)由二元數(shù)組組成的數(shù)組牡属,也可以是逐個(gè)生成二元數(shù)組的一個(gè)生成器票堵,等等。
  • map.size:返回 Map 中項(xiàng)目的個(gè)數(shù)逮栅。
  • map.has(key):測試一個(gè)鍵名是否存在悴势,類似 key in obj
  • map.get(key):返回一個(gè)鍵名對應(yīng)的值措伐,若鍵名不存在則返回 undefined特纤,類似 obj[key]
  • map.set(key, value):添加一對新的鍵值對侥加,如果鍵名已存在就覆蓋捧存。
  • map.delete(key):按鍵名刪除一項(xiàng),類似delete obj[key]担败。
  • map.clear():清空Map昔穴。
  • map[Symbol.iterator]():返回遍歷所有項(xiàng)的迭代器,每項(xiàng)用一個(gè)鍵和值組成的二元數(shù)組表示提前。
  • map.forEach(f) 類似for (let [key, value] of map) { f(value, key, map); }吗货。這里詭異的參數(shù)順序,和Set中一樣狈网,是對應(yīng)著Array.prototype.forEach()宙搬。
  • map.keys():返回遍歷所有鍵的迭代器。
  • map.values():返回遍歷所有值的迭代器拓哺。
  • map.entries():返回遍歷所有項(xiàng)的迭代器害淤,就像map[Symbol.iterator]()。實(shí)際上拓售,它們就是同一個(gè)方法,不同名字镶奉。

轉(zhuǎn)換方法

Set => Array

  • 擴(kuò)展運(yùn)算符(...
var a = [...new Set([1,2,3,4])]
a // [1,2,3,4]

Map => Array

var map = new Map();
map.set(true, 7);
map.set({a: '1'}, ['abc']);
var arr = [...map];
arr // [[true, 7], [{ a: '1' }, ['abc']]]

Array => Map

new Map([
  [true, 7],
  [{ a: '1' }, ['abc']]
])// Map {true=>7, {a: '1'}=>['abc']}

Map 轉(zhuǎn)換為對象

如果所有 Map 的鍵都是字符串础淤,它可以轉(zhuǎn)為對象崭放。

function strMapToObj(strMap) {
  let obj = Object.create(null); // 創(chuàng)建新的空對象
  for (let [k,v] of strMap) {    // 遍歷 Map 對象
    obj[k] = v;                  // 賦值空對象
  }
  return obj;
}

const myMap = new Map()
  .set('yes', true)
  .set('no', false);
strMapToObj(myMap)
// { yes: true, no: false }

例子來自 ECMAScript 6 入門 阮一峰

對象轉(zhuǎn)為Map

function objToStrMap(obj) {
  let strMap = new Map();
  for (let key of Object.keys(obj)) {
      strMap.set(key, obj[key]);
  }
  return strMap;
}

objToStrMap({yes: true, no: false})
// Map {"yes" => true, "no" => false}

例子來自 ECMAScript 6 入門 阮一峰

Map 轉(zhuǎn)為 Json

Map 轉(zhuǎn)為 Json 分為兩種情況

  1. 對象Json, Map 的鍵為字符串
function strMapToJson(strMap) {
  return JSON.stringify(strMapToObj(strMap))
}
let myMap = new Map().set('yes', true).set('no', false);
strMapToJson(myMap)
// '{"yes":true,"no":false}'
  1. 數(shù)組Json,Map 的鍵有非字符串
function mapToArrayJson(map) {
  return JSON.stringify([...map]);
}

let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
mapToArrayJson(myMap)
// '[[true,7],[{"foo":3},["abc"]]]'

例子來自 ECMAScript 6 入門 阮一峰

Json 轉(zhuǎn)為 Map

  1. 鍵名都是字符串

function jsonToStrMap(jsonStr) {
  return objToStrMap(JSON.parse(jsonStr));
}

jsonToStrMap('{"yes": true, "no": false}')
// Map {'yes' => true, 'no' => false}
  1. 整個(gè) JSON 就是一個(gè)數(shù)組

function jsonToMap(jsonStr) {
  return new Map(JSON.parse(jsonStr));
}

jsonToMap('[[true,7],[{"foo":3},["abc"]]]')
// Map {true => 7, Object {foo: 3} => ['abc']}

例子來自 ECMAScript 6 入門 阮一峰

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鸽凶,一起剝皮案震驚了整個(gè)濱河市币砂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌玻侥,老刑警劉巖决摧,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異凑兰,居然都是意外死亡掌桩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進(jìn)店門姑食,熙熙樓的掌柜王于貴愁眉苦臉地迎上來波岛,“玉大人,你說我怎么就攤上這事音半≡蚩剑” “怎么了?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵曹鸠,是天一觀的道長煌茬。 經(jīng)常有香客問我,道長彻桃,這世上最難降的妖魔是什么坛善? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮叛薯,結(jié)果婚禮上浑吟,老公的妹妹穿的比我還像新娘。我一直安慰自己耗溜,他們只是感情好组力,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著抖拴,像睡著了一般燎字。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上阿宅,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天候衍,我揣著相機(jī)與錄音,去河邊找鬼洒放。 笑死蛉鹿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的往湿。 我是一名探鬼主播妖异,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼惋戏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了他膳?” 一聲冷哼從身側(cè)響起响逢,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎棕孙,沒想到半個(gè)月后舔亭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蟀俊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年钦铺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片欧漱。...
    茶點(diǎn)故事閱讀 38,747評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡职抡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出误甚,到底是詐尸還是另有隱情缚甩,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布窑邦,位于F島的核電站擅威,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏冈钦。R本人自食惡果不足惜郊丛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瞧筛。 院中可真熱鬧厉熟,春花似錦、人聲如沸较幌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乍炉。三九已至绢片,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間岛琼,已是汗流浹背底循。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留槐瑞,地道東北人熙涤。 一個(gè)月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親灭袁。 傳聞我的和親對象是個(gè)殘疾皇子猬错,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內(nèi)容