ES6--Set & Map

這個筆記是摘錄一些 set & map 裏面比較重要的知識點,沒有特別細,須要先對語法有一些瞭解的再看,應該算是一個記憶的文檔吧。
Set
1.向Set加入值的時候, 不會發生類型轉換,因此 5"5"是兩個不一樣的值。它相似於精確相等運算符( ===),主要的區別是 NaN等於自身,而精確相等運算符認爲 NaN不等於自身。
2.新的數組去重的方法: [...new Set(array)]
3.另外兩個對象始終是不相等的 
4.Set實例的方法分爲兩大類:操做方法(用於操做數據)和遍歷方法(用於遍歷成員)。
操做方法(用於操做數據):
  • add(value):添加某個值,返回Set結構自己。
  • delete(value):刪除某個值,返回一個布爾值,表示刪除是否成功。
  • has(value):返回一個布爾值,表示該值是否爲Set的成員。
  • clear():清除全部成員,沒有返回值。
遍歷方法(用於遍歷成員):
  • keys():返回鍵名的遍歷器
  • values():返回鍵值的遍歷器
  • entries():返回鍵值對的遍歷器
  • forEach():使用回調函數遍歷每一個成員

  須要特別指出的是,Set的遍歷順序就是插入順序。這個特性有時很是有用,好比使用Set保存一個回調函數列表,調用時就能保證按照添加順序調用。javascript

  

5.這就提供了去除數組重複成員的另外一種方法
   
 function dedupe(array) {
              return Array.from(new Set(array));
    }
 dedupe([1, 1, 2, 3]) // [1, 2, 3]

 

 

7.注意,rest參數以後不能再有其餘參數(即只能是最後一個參數),不然會報錯
8.擴展運算符 ...
   擴展運算符(spread)是三個點(...)。它比如rest參數的逆運算,將一個數組轉爲用逗號分隔的參數序列。
   擴展運算符( ...)內部使用 for...of循環,因此也能夠用於Set結構。
    替代數組的apply方法 
       // ES5的寫法 
     Math.max.apply(null, [14, 3, 77])
     // ES6的寫法
     Math.max(...[14, 3, 77]) 
     // 等同於
    Math.max(14, 3, 77);
另外一個例子是經過 push函數,將一個數組添加到另外一個數組的尾部
// ES5的寫法
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
Array.prototype.push.apply(arr1, arr2); 
// ES6的寫法
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1.push(...arr2);

下面是另一個例子。java

// ES5
new (Date.bind.apply(Date, [null, 2015, 1, 1]))
// ES6
new Date(...[2015, 1, 1]);

9.運算符的擴展應用:json

     合併數組
     與解構賦值結合     //   若是將擴展運算符用於數組賦值,只能放在參數的最後一位,不然會報錯
     函數的返回值
     字符串
     實現了Iterator接口的對象
     Map和Set結構,Generator函數
10.嚴格模式
    從ES5開始,函數內部能夠設定爲嚴格模式。 《ECMAScript 2016標準》作了一點修改,規定只要函數參數使用了默認值、解構賦值、或者擴展運算符,那麼函數內部就不能顯式設定爲嚴格模式,不然會報錯。
11.name屬性 
    須要注意的是,ES6對這個屬性的行爲作出了一些修改。若是將一個匿名函數賦值給一個變量,ES5的name屬性,會返回空字符串,而ES6的name屬性會返回實際的函數名。
     Function構造函數返回的函數實例, name屬性的值爲「anonymous」。
12.set 的遍歷操做, 擴展運算符(...)內部使用for...of循環,因此也能夠用於Set結構。 
    注意點:若是是用了set對象的返回的也是一個set對象
    map() / filter() / 並集 / 交集 / 差集 的使用
    若是想在遍歷操做中,同步改變原來的Set結構,目前沒有直接的方法,但有兩種變通方法。一種是利用原Set結構映射出一個新的結構,而後賦值給原來的Set結構;另外一種是利用 Array.from方法。
map

1.Object結構提供了「字符串—值」的對應,Map結構提供了「值—值」的對應,是一種更完善的Hash結構實現。若是你須要「鍵值對」的數據結構,Map比Object更合適。數組

2.對map操做方法和便利方法的總結:數據結構

    get set size has delete clearapp

  keys() values() entries() forEach()函數

3.能夠是對象,數組 字符串true和布爾值true是兩個不一樣的鍵。 spa

                 若是對同一個鍵屢次賦值,後面的值將覆蓋前面的值。
                 若是讀取一個未知的鍵,則返回 undefined
                 注意,只有對同一個對象的引用,Map結構纔將其視爲同一個鍵。這一點要很是當心 
var map = new Map();
map.set(['a'], 555);
map.get(['a']) // undefined
上面代碼的set和get方法,表面是針對同一個鍵,但實際上這是兩個值,內存地址是不同的,所以get方法沒法讀取該鍵,返回undefined。  

  

4.在ES6中,有三類數據結構原生具有Iterator接口:數組、某些相似數組的對象、Set和Map結構。
Symbol.iterator構造函數
    let arr = ['a', 'b', 'c'];
    let iter = arr[Symbol.iterator]();
    iter.next() // { value: 'a', done: false }
    iter.next() // { value: 'b', done: false }
    iter.next() // { value: 'c', done: false }
    iter.next() // { value: undefined, done: true }      
//這裏有點相似match方法,下一個下一個知道比那裏不到爲止 

5.for ....of  prototype

一個數據結構只要部署了Symbol.iterator屬性,就被視爲具備iterator接口,就能夠用for...of循環遍歷它的成員。也就是說,for...of循環內部調用的是數據結構的Symbol.iterator方法。設計

        const arr = ['red', 'green', 'blue'];
        let iterator  = arr[Symbol.iterator]();
        for(let v of arr) {
          console.log(v);      // red green blue
        }

         for(let v of iterator) {
          console.log(v);      // red green blue
        }

JavaScript原有的for...in循環,只能得到對象的鍵名,不能直接獲取鍵值。ES6提供for...of循環,容許遍歷得到鍵值。

能夠代替forEach循環

        var arr = ['a', 'b', 'c', 'd'];
  
        for (let a in arr) {
          console.log(a); // 0 1 2 3
        }
        
        for (let a of arr) {
          console.log(a); // a b c d
        }
  1. for...of循環調用遍歷器接口,數組的遍歷器接口只返回具備數字索引的屬性。這一點跟for...in循環也不同 / for...of循環不會返回數組arr的foo屬性。
  2. for...of 循環的幾個缺點:
    1. 數組的鍵名是數字,可是for...in循環是以字符串做爲鍵名「0」、「1」、「2」等等。
    2. for...in循環不只遍歷數字鍵名,還會遍歷手動添加的其餘鍵,甚至包括原型鏈上的鍵。 某些狀況下,for...in循環會以任意順序遍歷鍵名。 總之,for...in循環主要是爲遍歷對象而設計的,不適用於遍歷數組。

6.map 的forEach方法   

map.forEach(function(value, key, map) {

  console.log("Key: %s, Value: %s", key, value);

});

7.map和其餘各個數據類型的轉化

(1)Map轉爲數組

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

(2)數組轉爲Map

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

(3)Map轉爲對象

若是全部Map的鍵都是字符串,它能夠轉爲對象。

function strMapToObj(strMap) {
  let obj = Object.create(null);
  for (let [k,v] of strMap) {
    obj[k] = v;
  }
  return obj;
}

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

(4)對象轉爲Map

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

objToStrMap({yes: true, no: false})
// [ [ 'yes', true ], [ 'no', false ] ]

(5)Map轉爲JSON

Map轉爲JSON要區分兩種狀況。一種狀況是,Map的鍵名都是字符串,這時能夠選擇轉爲對象JSON。

function strMapToJson(strMap) {
  return JSON.stringify(strMapToObj(strMap));
}

let myMap = new Map().set('yes', true).set('no', false);
strMapToJson(myMap)
// '{"yes":true,"no":false}'

另外一種狀況是,Map的鍵名有非字符串,這時能夠選擇轉爲數組JSON。

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"]]]'

(6)JSON轉爲Map

JSON轉爲Map,正常狀況下,全部鍵名都是字符串。

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

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

可是,有一種特殊狀況,整個JSON就是一個數組,且每一個數組成員自己,又是一個有兩個成員的數組。這時,它能夠一一對應地轉爲Map。這每每是數組轉爲JSON的逆操做。

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

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

完畢!

相關文章
相關標籤/搜索