一.前言
文章主要講JS Map對象的用法和如何手寫Map罐农,非常適合初步學(xué)習(xí)了JS的同學(xué),適當(dāng)?shù)膶W(xué)會手寫JS源碼的技能催什,對JS理解和面試都有很大的幫助涵亏。大多數(shù)人都知道Map方法的使用,但是在網(wǎng)上對Map源碼實現(xiàn)的文章很少,希望通過這篇文章可以幫助到大家對Map方法的理解溯乒。
說在前面
Map 對象保存鍵值對,并且能夠記住鍵的原始插入順序豹爹。任何值(對象或者原始值) 都可以作為一個鍵或一個值裆悄。本文會先簡單介紹用法,再介紹手寫Map,
想讓Map現(xiàn)原形就快快花幾分鐘時間瀏覽這篇文章吧臂聋!
二. Map方法的使用
Map是一組鍵值對的結(jié)構(gòu)光稼,具有極快的查找速度。
舉個例子孩等,假設(shè)要根據(jù)同學(xué)的名字查找對應(yīng)的成績艾君,如果用Array實現(xiàn),需要兩個Array:
var names = ['lm', 'dz', 'xxy'];
var scores = [100, 90, 80];
我們需要實現(xiàn)這個要求肄方,就先要遍歷names
數(shù)組冰垄,找到需要查詢同學(xué)名字的位置,然后去scores
數(shù)組中找到相應(yīng)的位置权她,取出成績虹茶。這樣的話有兩個缺點:
- 數(shù)組越長,需要查詢耗時越長隅要。
- 如果數(shù)據(jù)很多蝴罪,導(dǎo)入數(shù)據(jù)的時候,很容易出錯步清。
如果用Map實現(xiàn)要门,只需要一個“名字”-“成績”的對照表,直接根據(jù)名字查找成績廓啊,一個鍵(名字)和對應(yīng)一個值(成績)進(jìn)行綁定欢搜,無論這個表有多大,谴轮,也不用擔(dān)心出錯狂巢。用JavaScript使用Map實現(xiàn)如下:
var m = new Map([['lm', 100], ['dz', 90], ['xxy', 80]]);
m.get('lm'); //100
m.size();//3
m.set('xp', 90); // 添加新的key-value
m.delete('xxy'); // 刪除key 'xxy'
通過Map的get
方法查詢到lm
同學(xué)100分,用size
獲取有多少個鍵值對,用set
方法添加xp
的成績书聚,用delete
方法刪除xxy
的成績唧领。
我們需要注意的是一個key只能對應(yīng)一個value,多次對一個key放入value雌续,后面的值會把前面的值沖掉:
var m = new Map();
m.set('xp', 70);
m.set('xp', 90);
m.get('xp'); // 90
三.手寫Map方法
想要手寫Map方法斩个,首先需要知道的是它ES6標(biāo)準(zhǔn)新增的數(shù)據(jù)類型,是鍵/值對的集合驯杜。這個數(shù)據(jù)類型受啥,可以使用很多方法來操作它。下面就讓我們,小手一敲滚局,讓它現(xiàn)出原形吧~
-
定義Map方法
寫一個方法首當(dāng)其沖的當(dāng)然是要定義它居暖,并且聲明方法里面的參數(shù)。
/**
*
* 描述:js實現(xiàn)的map方法
* @returns {Map}
*/
function Map(){
var struct = function(key, value) {
this.key = key;
this.value = value;
};
}
-
寫set方法
需要添加鍵值對藤肢,我們需要注意的是太闺,如果之前就存在這個鍵值對,需要對它的
value
進(jìn)行覆蓋更新嘁圈。如果不存在省骂,則直接保存這對鍵值。
// 添加map鍵值對
var set = function(key, value){
//遍歷數(shù)組最住,如果存在钞澳,則進(jìn)行覆蓋
for (var i = 0; i < this.arr.length; i++) {
if ( this.arr[i].key === key ) {
this.arr[i].value = value;
return;
}
};
//之前的數(shù)據(jù)里面沒有這個對鍵值,直接對應(yīng)保存
this.arr[this.arr.length] = new struct(key, value);
};
-
寫get方法
完成
get
方法涨缚,需要實現(xiàn)根據(jù)key
獲取value
轧粟,如果key
存在則獲取對應(yīng)的value
,否則返回null
,代碼如下:
// 根據(jù)key獲取value
var get = function(key) {
for (var i = 0; i < this.arr.length; i++) {
if ( this.arr[i].key === key ) {
return this.arr[i].value;
}
}
return null;
};
- 寫remove方法
Map
方法中可可以通過key
,來完成刪除鍵值對脓魏。要刪除鍵值對逃延,作者想到的是,不管存在與否轧拄,遍歷所有數(shù)組揽祥,先把棧頂?shù)?code>v.key,用pop
拿出,如果需要刪除的key
與v.key
一致檩电,則continue
,否則用unshift(v)
,將其恢復(fù)拄丰。代碼如下:
// 根據(jù)key刪除
var remove = function(key) {
var v;
for (var i = 0; i < this.arr.length; i++) {
v = this.arr.pop();
if ( v.key === key ) {
continue;
}
this.arr.unshift(v);
}
};
- 寫size和isEmpty方法
這個兩個方法的實現(xiàn)都很簡單,相信每個人都會俐末,我就直接上代碼:
// 獲取map鍵值對個數(shù)
var size = function() {
return this.arr.length;
};
// 判斷map是否為空
var isEmpty = function() {
return this.arr.length <= 0;
};
四料按、驗證與總結(jié)
- 驗證
一個方法有沒有寫對,最好的驗證卓箫,就是實踐出真知载矿,下面我附上所有代碼吧
function Map(){
var struct = function(key, value) {
this.key = key;
this.value = value;
};
// 添加map鍵值對
var set = function(key, value){
for (var i = 0; i < this.arr.length; i++) {
if ( this.arr[i].key === key ) {
this.arr[i].value = value;
return;
}
};
this.arr[this.arr.length] = new struct(key, value);
};
// 根據(jù)key獲取value
var get = function(key) {
for (var i = 0; i < this.arr.length; i++) {
if ( this.arr[i].key === key ) {
return this.arr[i].value;
}
}
return null;
};
// 根據(jù)key刪除
var remove = function(key) {
var v;
for (var i = 0; i < this.arr.length; i++) {
v = this.arr.pop();
if ( v.key === key ) {
continue;
}
this.arr.unshift(v);
}
};
// 獲取map鍵值對個數(shù)
var size = function() {
return this.arr.length;
};
// 判斷map是否為空
var isEmpty = function() {
return this.arr.length <= 0;
};
this.arr = new Array();
this.get = get;
this.set = set;
this.remove = remove;
this.size = size;
this.isEmpty = isEmpty;
}
var map=new Map();
map.set("xxyang",100);
map.set("xxyang",90);
map.set("xp","dz");
console.log(map.get('xxyang'));//90
console.log(map.get('xp')); //dz
console.log(map.size());//2
map.remove("xxyang");
console.log(map.size());//1
console.log(map.get("xxyang"));//null
用vscode
運行得到如下結(jié)果:
結(jié)果無誤,也可以覆蓋烹卒。
Map
方法的簡單實現(xiàn)就完成啦闷盔,看完文章你可以去試試其他方法的實現(xiàn)~
- 總結(jié)
- Map 的鍵可以是任意值,包括函數(shù)旅急、對象逢勾、基本類型。
- Map 中的鍵值是有序的藐吮,因此溺拱,當(dāng)對它進(jìn)行遍歷時逃贝,Map 對象是按插入的順序返回鍵值。
- Map 可直接進(jìn)行迭代
- Map 在涉及頻繁增刪鍵值對的場景下會有些性能優(yōu)勢迫摔。
- 對于小白來說沐扳,挑選一個簡單的方法來進(jìn)行源碼實現(xiàn),真的是不錯的選擇句占,可以打破內(nèi)心的恐懼沪摄,如果你也有這種恐懼,快去試試吧辖众。手寫源碼卓起,面試澈途矗考凹炸,雖然有許多大佬,也發(fā)表了相關(guān)文章昼弟,但是靠背是記不住的啤它,還是要自己寫寫。
結(jié)束
恭喜你看完這篇文章啦舱痘,如果有錯誤的話就麻煩大家給我指出來吧变骡!覺得不錯的話,來個??鼓勵一下芭逝,哈哈