ES6學習筆記(10)----Set和Map數據結構

来源:https://www.cnblogs.com/carolddz/archive/2018/04/08/8743497.html
-Advertisement-
Play Games

參考書《ECMAScript 6入門》http://es6.ruanyifeng.com/Set和Map數據結構1.Set 基本用法 Set是一種新的數據結構,它的成員都是唯一的不重覆的。 let s1 = new Set(); s1.add({"name":"123"}); s1 // Set(1 ...


參考書《ECMAScript 6入門》
http://es6.ruanyifeng.com/

Set和Map數據結構

1.Set
  基本用法
    Set是一種新的數據結構,它的成員都是唯一的不重覆的。
    let s1 = new Set();
    s1.add({"name":"123"});
    s1 // Set(1){{"name":"123"}}

    let s2 = new Set([1,2,3,4,4,3,2,1]);
    s2 //Set(4) {1, 2, 3, 4}
    Set判斷重覆的方式是精準相等,同Object.is()
    NaN == NaN //false
    NaN === NaN //false
    Object.is(NaN,NaN)//true
    let s3 = new Set();
    s3.add(NaN);
    s3.add(NaN);
    s3 //Set(1) {NaN} //Set添加的成員都是不重覆的
    Object.is({},{});//false 兩個空對象總是不相等
    s3.add({});
    s3.add({});
    s3 //Set(3) {NaN, {}, {}}
    Set實例的屬性和方法
  屬性
    Set.prototype.constructor:返回set結構的構造器 ƒ Set() { [native code] }
    Set.prototype.size:返回set存儲數據的大小
  方法
    add:向set結構中添加成員
    has:判斷set中是否有某個成員
    delete:刪除set中的某個成員
    clear:清楚set中的所有成員
    let s1 = new Set();
    s1.add({"test":"11"});
    s1.add({"test":"22"});
    s1//Set(2) {{"test":"11"}, {"test":"22"}}
    s1.has("test");//false
    s1.delete("test");//false
    s1.has({"test":"11"});//false
    s1.delete({"test":"11"});//false
    let s2 = new Set();
    s2.add("name");
    s2.has("name");//true
  對象與Set解構判斷是否含有某一個key值的不同方式
    var obj = {
      name : "test",
      value : "123"
    }
    obj.name//"test"
    obj[name]//"test"
    obj.value//"123"
    obj[value]//"123"

    let s4 = new Set();
    s4.add("name");
    s4.add("value");
    s4.has("name");//true
  遍歷操作
    (1)數組結構,對象結構,set結構調用keys(),values(),entries()遍歷比較
       數組結構
       let arr = [1,2,3,4,5];
       for(let k of arr.keys()){
         console.log(k);//0 1 2 3 4
       }
       for(let v of arr.values()){
         console.log(v);//1 2 3 4 5
       }
       for(let entry of arr.entries()){
         console.log(entry);//[0,1] [1,2] [2,3] [3,4] [4,5]
       }
   對象結構
    let  obj = {
      name : "test",
      size : 13,
      color : "red"
    }
    for(let k of Object.keys(obj)){
      console.log(k);//name size color
    }
    for(let v of Object.values(obj)){
      console.log(v);//test 13 red
    }
    for(let o of Object.entries(obj)){
      console.log(o);//["name", "test"] ["size", 13] ["color", "red"]
    }
   Set 結構:set結構沒有鍵名,只有鍵值,所以keys和valus方法返回值一致,entries每次調用返回的是一個數組,數組成員是這個entry的鍵名和鍵值,所以兩個數組成員是相等的
    let s = new Set();
    s.add({name : "test"});
    s.add({age : 13});
    s.add({color :"red"});
    for(let k of s.keys()){
      console.log(k);//{name: "test"}  {age: 13}  {color: "red"}
    }
    for(let v of s.values()){
      console.log(v);//{name: "test"}  {age: 13}  {color: "red"}
    }
    for(let o of s.entries()){
      console.log(o);//[{name: "test"}, {name: "test"}]  [{age: 13},{age: 13}] [{color: "red"},{color: "red"}]
    }
    for(let v of s){
      console.log(v);//{name: "test"}  {age: 13}  {color: "red"} Set結構的實例預設是可遍歷的,預設遍歷器是values()方法
    }
  (2)數組結構與set結構調用forEach()遍歷比較
     數組結構
     let arr = [1,2,3,4,5];
     arr.forEach(function(i,v){
       v = v + 2;
       console.log(v);
     });// 2 3 4 5 6
     arr.forEach((i,v) => console.log(v*5));//0 5 10 15 20
     Set結構
     let s = new Set([1,2,3,4,5]);
       s.forEach(function(i,v){
       console.log(v - 1);
     });//0 1 2 3 4
    等同於
    s.forEach((i,v) => console.log(v - 1););//0 1 2 3 4
  遍歷的應用
    擴展運算符(...)內部使用for...of迴圈,因此set結構也可以使用
    let s = new Set();
    s.add({name : "test"});
    s.add({age : 13});
    s.add({color :"red"});
    [...s] //[{name : "test"}, {age : 13}, {color :"red"}]
    目前可以使用擴展運算符(...)的結構:Array,Object,Set
    數組的map和filter也可以間接用在Set結構上
    let s = new Set([1,2,3,4,5]);
    s = new Set([...s].map(x => x+2));//Set(5) {3, 4, 5, 6, 7}
    s = new Set([...s].filter(x => (x%2) === 0));//Set(2) {2, 4}
    使用Set實現交集,並集,差集
    let s1 = new Set([1,2,3,4,5]);
    let s2 = new Set([3,4,5,6,7]);
    並集
    let s3 = new Set([...s1,...s2]);
    s3 //Set(7) {1, 2, 3, 4, 5, 6, 7}
    交集
    let s4 = new Set([...s1].filter(x => s2.has(x)))
    s4 //Set(3) {3, 4, 5}
    差集
    let s5 = new Set([...s1].filter(x => !s2.has(x)))
    s5 //Set(2) {1, 2}
2.WeakSet
  含義:WeakSet和Set一樣都是不可重覆的數據結構,但是WeakSet的成員只能是對象
    let s1 = new Set();
    s1.add(3);
    s1.add({name : "test"});
    s1 //Set(2) {3, {name : "test"}}
    let s2 = new WeakSet();
    s2.add({name : "test"});
    s2 //WeakSet {{name : "test"}}
    s2.add(3);//Uncaught TypeError: Invalid value used in weak set 只能接受加入對象成員
    WeakSet中的對象都是弱引用,如果其他地方沒有引用這個對象,垃圾回收機制就會自動回收該對象所占用的記憶體,不考慮對象還存在於WeakSet中
    語法
    let w1 = new WeakSet();
    w1.add({name : "test"});
    除對象外,數組以及類數組都可以添加到weakSet結構中
    let dd = document.querySelectorAll("tr");
    w1.add(dd);
    w1.add([1,2]);  
    w1 //WeakSet {{name : "test"},NodeList(626), [1,2]}
    let a = [3,4];
    w1.add(a);//WeakSet {{name : "test"},NodeList(626), [1,2],[3,4]}
    let w2 = new WeakSet(a);
    //Uncaught TypeError: Invalid value used in weak set  
    //此處數組a的成員是單個數值,不是對象,調用WeakSet構造器生成WeakSet結構時,被加入到WeakSet中的是數組的成員,由於成員不是對象,所以報錯
    WeakSet結構有三個方法add,has和delete
    WeakSet.prototype.add:向WeakSet結構中添加一個新成員
    WeakSet.prototype.has:返回一個布爾值,表示某一個值是否存在WeakSet實例當中
    WeakSet.prototype.delete:清除WeakSet實例的指定成員
    w1.add(window);
    w1.has(window);//true
    w1.delete(window);//true
    WeakSet沒有size屬性,不能遍歷,因為它的成員都是弱引用,隨時可能消失。
  數組去重的方法
    (1)Set結構與擴展運算符(...)相結合
    let arr = [1,2,3,4,3,2,'a','aa','b','a'];
    [...new Set(arr)] //[1, 2, 3, 4, "a", "aa", "b"]
3.Map
  含義:Map是一種鍵值對構成的數據結構,不同於對象,map的鍵可以是任何簡單值或者對象。
  基本用法
    set:set(key,value) 向Map結構中添加鍵值對。返回值map因此可以鏈式調用
    get:get(key) 讀取Map結構中鍵值為key所對應的value值
    has:has(key) 判斷Map結構中是否含有鍵值為key的鍵值對,返回值是布爾類型
    delete:delete(key) 刪除Map結構中鍵值為key所對應的鍵值對
    clear:map.clear() 清除map結構實例的所有成員
  生成Map實例的方法
    (1)先用new Map構造器的方式生成map結構,再使用基本方法將數據添加到Map結構中
    let m1 = new Map();
    m1.set(0,"t1");
    m1.set({name : "maptest"},"test2");
    m1.set("color",2);
    m1.get({name : "maptest"});//undefined  
    //{name : "maptest"} == {name : "maptest"} false     {name : "maptest"} === {name : "maptest"} false   Object.is({name : "maptest"},{name : "maptest"})
    //雖然看起來值相同,但是{name : "maptest"} == {name : "maptest"} 左右兩個對象是不同的記憶體地址,所以是兩個對象
    //'color' === 'color' true   ['color'] === ['color'] false
    let obj = {name : "maptest"};
    m1.set(obj,"t3");
    m1.get(obj);// "t3"
    m1.has(0);//true
    m1.delete('color');//true
    m1.has('color');//false
    (2)使用new Map構造器創建map實例時,
    將有iterator迭代器介面的數據結構,並且此結構成員是一個雙成員的數組,傳入構造器中做參數
    有iterator迭代器介面的結構如數組,類數組對象,set,map
    數組
    let m2 = new Map([["name","value"]]);
    m2 //Map(1) {"name" => "value"}
    m2.get("name");//"value"
  類數組對象
    let divArr = document.querySelectorAll("tr");
    let arr = [];
    function test(){
      [...divArr].forEach(function(value,index){
        arr.push([index,value]);     
      });
    }
    test();
    arr //[[0, NodeList(69)]]
    let m3 = new Map(arr);
    m3.get(0);//NodeList(69) [n1,n2,n3......]
  Set數據結構
    let s1 = new Set([[1,10],[2,20]]);
    let m4 = new Map(s1);
    m4.get(1);//10
    m4.has(2);//true
  Map數據結構
    let m5 = new Map([["run","fast"]]);
    let m6 = new Map(m5);
    m6.get("run");//"fast"
    如果針對同一個鍵重覆賦值,則後賦的值會代替先賦的值
    m6.set("run","slow");
    m6.get("run");//"slow"
    Map的鍵實際上是跟記憶體地址綁定的,只要記憶體地址不一樣,就視為兩個值。
    'a' === 'a' true 簡單值嚴格相等,map視為同一個值
    ['a'] === ['a'] false 記憶體地址不同,map視為不同的值
  實例的屬性和操作方法
  屬性
  size:返回Map結構的成員總數
  方法
  set/get/has/delete/clear
  遍歷方法
    keys()/values()/entries()/forEach()用法同set,遍歷順序即插入順序。
    let m = new Map();
    m.set(name,"test");
    m.set(age,13);
    m.set(color,"red");
    for(let k of m.keys()){
      console.log(k);//name age  color
    }
    for(let v of m.values()){
      console.log(v);//test  13  red
    }
    for(let o of m.entries()){
      console.log(o);//["name": "test"] ["age": 13] ["color": "red"]
    }
    for(let v of m){
      console.log(v);//["name": "test"] ["age": 13] ["color": "red"] map結構的實例預設是可遍歷的,預設遍歷器是entries()方法
    }
    m.forEach(function(v,i){
     console.log("key : "+i+",value : "+v);
    });
    //key : name,value : test
    //key : age,value : 13
    //key : color,value : red
    m.forEach(function(v,i){
      console.log(navigator.userAgent);
    },navigator);
    //3 Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
    //forEach除了回調函數還可以傳第二個參數,可以用來綁定對象
  Map與其他數據結構互相轉換
     let m = new Map();
     m.set(name,"test");
     m.set(age,13);
     m.set(color,"red");
    (1)Map與數組互相轉換
       a.(...)擴展運算符可以將map轉換成數組
         console.log([...m]);//[["name": "test"],["age": 13],["color": "red"]]
       b.通過將符合標準的數組傳入map構造器中生成map實例,可以實現數組轉換成map結構
       let arr = [[0,'a'],[1,'b'],[2,'c']];
       let m = new Map(arr);
       m //Map(3) {0 => "a", 1 => "b", 2 => "c"}
    (2)Map與對象互相轉換
     a.通過迴圈遍歷將map的key值賦值給對象的屬性名,value值賦值給對象的屬性值,可以實現map轉換成對象。
     let m = new Map([[{color : "black"},"22"]]).set(0,'test').set(1,'a');
     m //Map(3) {{color: "black"} => "22", 0 => "test", 1 => "a"}
     let obj = {};
     for(let [k,v] of m){
       obj[k] = v;
     }
     obj //{0: "test", 1: "a", [object Object]: "22"}
        //{color: "black"} 這個鍵名是非字元串的,所以被轉化成了[oject object]
     b.對象轉換成map 遍歷對象,將對象的屬性名設置成map的key值,將對象的屬性值設置成map的value值
     let obj = {0: "test", 1: "a", 2: "22"}
     let m = new Map(Object.entries(obj));
     m //Map(3) {"0" => "test", "1" => "a", "2" => "22"}
    (3)Map與JSON互相轉換
       a.可以通過map-->Array-->json或map-->Object-->json的兩種方式實現map轉換成json
       let m = new Map([[{color : "black"},"22"]]).set(0,'test').set(1,'a');
       m //Map(3) {{color: "black"} => "22", 0 => "test", 1 => "a"}
       JSON.stringify([...m]);//'[[{"color":"black"},"22"],[0,"test"],[1,"a"]]'
       
       let m = new Map([[2,"22"]]).set(0,'test').set(1,'a');
       m //Map(3) {2 => "22", 0 => "test", 1 => "a"}
       let obj = {};
       for(let [k,v] of m){
           obj[k] = v;
       }
       obj //{0: "test", 1: "a", 2: "22"}
       JSON.stringify(obj);//'{"0":"test","1":"a","2":"22"}'
       b.可以通過json-->Array-->map或json-->Object-->map的兩種方式實現map轉換成json
       let j1 = '[[{"color":"black"},"22"],[0,"test"],[1,"a"]]';
       let m = new Map(JSON.parse(j1));
       m //Map(3) {{"color":"black"} => "22", 0 => "test", 1 => "a"}
       
       let j1 = '{"0":"test","1":"a","2":"22"}';
       let obj = JSON.parse(j1);
       let m = new Map(Object.entries(obj));
       m //Map(3) {"0" => "test", "1" => "a", "2" => "22"}
4.WeakMap
  含義:用於生成鍵值對的集合,但是鍵名只能是對象或者null,而且WeakMap鍵名所引用的對象是弱引用。
  語法:可以通過set來向WeakMap添加結構,也可以使用向WeakMap構造器中傳參數的方式生成WeakMap結構
    set/get/has/delete
    let w1 = new WeakMap();
    w1.set({name : "test"},"12");
    w1.has({name : "test"});//false {name : "test"} === {name : "test"} 記憶體地址不同,WeakMap視為不同的值
    let obj = {name : "test1"};
    w1.set(obj,"0");
    w1.has(obj);//true
    w1.set(window,'window');
    w1.has(window);//true
    w1.delete(window);//true

    let a1 = [1,2,3],a2 = [4,5,6];
    let w2 = new WeakMap([[a1,'abc'],[a2,'def']]);
    w2 //WeakMap {Array(3) => "def", Array(3) => "abc"}
    w2.has(a2);//true
特點:同WeakSet,WeakMap鍵名指向的對象,不計入垃圾回收機制。
        因此,只要WeakMap鍵名所引用的對象的其他引用都被清除,垃圾回收機制就會釋放該對象所占用的記憶體。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、let和const:最基礎也很容易理解的,let是 聲明一個變數,const是聲明一個常量。 具體細節看如下實例代碼 2、解構賦值,簡單來說就是將等號兩邊寫成一樣的模式,然後進行對應的賦值。如下實例 ...
  • 在 Vue 中,父子組件的關係可以總結為 props向下傳遞,事件向上傳遞。父組件通過 props 給子組件下發數據,子組件通過事件給父組件發送消息。看看它們是怎麼工作的。 一、基本用法 組件不僅僅是要把模板的內容進行復用,更重要的是組件間要進行通信。 在組件中,使用選項props 來聲明需要從父級 ...
  • 在JS中代碼中同一功能塊中通常同時會用到單擊、雙擊事件,但通常會遇到一個問題,就是在雙擊的時候即執行了一次雙擊事件,而且還執行了兩次單擊事件。此類衝突在`ZTree`、`DHTMLX`中經常遇到。 ...
  • 作用域 可以這樣理解:作用域是一套規則,這套規則用來管理引擎在當前作用域及嵌套的子作用域根據標示符名稱查找變數。 作用域鏈 由當前環境和上層環境的一系列變數對象組成,它保證了當前執行環境對符合訪問許可權的變數和函數的有序訪問。 註釋: ...
  • 實用場景 一(處理類數組 如 arguments ) ...
  • // 深拷貝 // 判斷類型 console.log(checkType(1)); //[object Number] console.log(checkType('1')); //[object String] console.log(checkType(true)); //[object Boo ...
  • 一、什麼是組件 組件 (Component) 是 Vue.js 最強大的功能之一。組件可以擴展 HTML 元素,封裝可重用的代碼。 二、組件用法 組件需要註冊後才可以使用,註冊有全局註冊和局部註冊兩種方式。 2.1 全局註冊後,任何V ue 實例都可以使用。如: 要在父實例中使用這個組件,必須要在實 ...
  • 一、基本用法 你可以用 v-model 指令在表單 <input> 及 <textarea> 元素上創建雙向數據綁定。 但 v-model 本質上不過是語法糖。它負責監聽用戶的輸入事件以更新數據,並對一些極端場景進行一些特殊處理。 v-model 會忽略所有表單元素的 value、checked、s ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...