小手一敲,讓JS Map方法現(xiàn)原形

image

一.前言


文章主要講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)的位置权她,取出成績虹茶。這樣的話有兩個缺點:

  1. 數(shù)組越長,需要查詢耗時越長隅要。
  2. 如果數(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拿出,如果需要刪除的keyv.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é)果:

image

結(jié)果無誤,也可以覆蓋烹卒。Map方法的簡單實現(xiàn)就完成啦闷盔,看完文章你可以去試試其他方法的實現(xiàn)~

  • 總結(jié)
  1. Map 的鍵可以是任意值,包括函數(shù)旅急、對象逢勾、基本類型。
  2. Map 中的鍵值是有序的藐吮,因此溺拱,當(dāng)對它進(jìn)行遍歷時逃贝,Map 對象是按插入的順序返回鍵值。
  3. Map 可直接進(jìn)行迭代
  4. Map 在涉及頻繁增刪鍵值對的場景下會有些性能優(yōu)勢迫摔。
  5. 對于小白來說沐扳,挑選一個簡單的方法來進(jìn)行源碼實現(xiàn),真的是不錯的選擇句占,可以打破內(nèi)心的恐懼沪摄,如果你也有這種恐懼,快去試試吧辖众。手寫源碼卓起,面試澈途矗考凹炸,雖然有許多大佬,也發(fā)表了相關(guān)文章昼弟,但是靠背是記不住的啤它,還是要自己寫寫。

結(jié)束

恭喜你看完這篇文章啦舱痘,如果有錯誤的話就麻煩大家給我指出來吧变骡!覺得不錯的話,來個??鼓勵一下芭逝,哈哈

參考文章

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末塌碌,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子旬盯,更是在濱河造成了極大的恐慌台妆,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件胖翰,死亡現(xiàn)場離奇詭異接剩,居然都是意外死亡,警方通過查閱死者的電腦和手機萨咳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門懊缺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人培他,你說我怎么就攤上這事鹃两。” “怎么了舀凛?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵怔毛,是天一觀的道長。 經(jīng)常有香客問我腾降,道長拣度,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮抗果,結(jié)果婚禮上筋帖,老公的妹妹穿的比我還像新娘。我一直安慰自己冤馏,他們只是感情好日麸,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著逮光,像睡著了一般代箭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上涕刚,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天嗡综,我揣著相機與錄音,去河邊找鬼杜漠。 笑死极景,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的驾茴。 我是一名探鬼主播盼樟,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼锈至!你這毒婦竟也來了晨缴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤峡捡,失蹤者是張志新(化名)和其女友劉穎击碗,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體棋返,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡延都,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了睛竣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晰房。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖射沟,靈堂內(nèi)的尸體忽然破棺而出殊者,到底是詐尸還是另有隱情,我是刑警寧澤验夯,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布猖吴,位于F島的核電站,受9級特大地震影響挥转,放射性物質(zhì)發(fā)生泄漏海蔽。R本人自食惡果不足惜共屈,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望党窜。 院中可真熱鬧拗引,春花似錦、人聲如沸幌衣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽豁护。三九已至哼凯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間楚里,已是汗流浹背断部。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留腻豌,地道東北人家坎。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓嘱能,卻偏偏與公主長得像吝梅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子惹骂,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

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