小手一敲,讓JS Map方法現原形


一.前言


文章主要講JS Map對象的用法和如何手寫Map,很是適合初步學習了JS的同窗,適當的學會手寫JS源碼的技能,對JS理解和麪試都有很大的幫助。大多數人都知道Map方法的使用,可是在網上對Map源碼實現的文章不多,但願經過這篇文章能夠幫助到你們對Map方法的理解。web

說在前面

Map 對象保存鍵值對,而且可以記住鍵的原始插入順序。任何值(對象或者原始值) 均可以做爲一個鍵或一個值。本文會先簡單介紹用法,再介紹手寫Map, 想讓Map現原形就快快花幾分鐘時間瀏覽這篇文章吧!面試


二. Map方法的使用


Map是一組鍵值對的結構,具備極快的查找速度。數組

舉個例子,假設要根據同窗的名字查找對應的成績,若是用Array實現,須要兩個Array:bash

var names = ['lm', 'dz', 'xxy'];
var scores = [100, 90, 80];
複製代碼

咱們須要實現這個要求,就先要遍歷names數組,找到須要查詢同窗名字的位置,而後去scores數組中找到相應的位置,取出成績。這樣的話有兩個缺點:函數

  1. 數組越長,須要查詢耗時越長。
  2. 若是數據不少,導入數據的時候,很容易出錯。

若是用Map實現,只須要一個「名字」-「成績」的對照表,直接根據名字查找成績,一個鍵(名字)和對應一個值(成績)進行綁定,不管這個表有多大,,也不用擔憂出錯。用JavaScript使用Map實現以下:性能

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同窗100分,用size獲取有多少個鍵值對,用set方法添加xp的成績,用delete方法刪除xxy的成績。學習

咱們須要注意的是一個key只能對應一個value,屢次對一個key放入value,後面的值會把前面的值沖掉:ui

var m = new Map();
m.set('xp', 70);
m.set('xp', 90);
m.get('xp'); // 90
複製代碼

三.手寫Map方法

想要手寫Map方法,首先須要知道的是它ES6標準新增的數據類型,是鍵/值對的集合。這個數據類型,可使用不少方法來操做它。下面就讓咱們,小手一敲,讓它現出原形吧~this

  • 定義Map方法spa

    寫一個方法首當其衝的固然是要定義它,而且聲明方法裏面的參數。

/** 
    *  
    * 描述:js實現的map方法 
    * @returns {Map} 
    */  
   function Map(){  
       var struct = function(key, value) {  
        this.key = key;  
        this.value = value;  
       }; 
   }
複製代碼
  • 寫set方法

    須要添加鍵值對,咱們須要注意的是,若是以前就存在這個鍵值對,須要對它的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);  
        };  
複製代碼
  • 寫get方法

    完成get方法,須要實現根據key獲取value,若是key存在則獲取對應的value,不然返回null ,代碼以下:

//  根據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,來完成刪除鍵值對。要刪除鍵值對,做者想到的是,無論存在與否,遍歷全部數組,先把棧頂的v.key,用pop拿出,若是須要刪除的keyv.key一致,則continue,不然用unshift(v),將其恢復。代碼以下:

//   根據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方法

這個兩個方法的實現都很簡單,相信每一個人都會,我就直接上代碼:

//   獲取map鍵值對個數  
        var size = function() {  
         return this.arr.length;  
        };  
       // 判斷map是否爲空    
        var isEmpty = function() {  
         return this.arr.length <= 0;  
        };  
複製代碼

4、驗證與總結

  • 驗證

一個方法有沒有寫對,最好的驗證,就是實踐出真知,下面我附上全部代碼吧

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);  
        };  
       //  根據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;  
        };  
       //   根據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鍵值對個數  
        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運行獲得以下結果:

結果無誤,也能夠覆蓋。 Map方法的簡單實現就完成啦,看完文章你能夠去試試其餘方法的實現~

  • 總結
  1. Map 的鍵能夠是任意值,包括函數、對象、基本類型。
  2. Map 中的鍵值是有序的,所以,當對它進行遍歷時,Map 對象是按插入的順序返回鍵值。
  3. Map 可直接進行迭代
  4. Map 在涉及頻繁增刪鍵值對的場景下會有些性能優點。
  5. 對於小白來講,挑選一個簡單的方法來進行源碼實現,真的是不錯的選擇,能夠打破心裏的恐懼,若是你也有這種恐懼,快去試試吧。手寫源碼,面試常考,雖然有許多大佬,也發表了相關文章,可是靠背是記不住的,仍是要本身寫寫。

結束

恭喜你看完這篇文章啦,若是有錯誤的話就麻煩你們給我指出來吧!以爲不錯的話,來個👍鼓勵一下,哈哈

參考文章

相關文章
相關標籤/搜索