爲了方便你們更好的瞭解和學習set,我在這裏會將這些方法和屬性進行分類整理和講解javascript
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>數組去重</title> </head> <body> <script type="text/javascript"> const set=new Set(); //建立set數據結構 [1,1,2,3,4,5].forEach(x=>{ set.add(x); }) console.log(set); //1,2,3,4,5 for(let i of set){ console.log(i); } </script> </body> </html>
能夠看到向Set添加成員時,不會添加劇復的值html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div></div> <div></div> <div></div> <div></div> <div></div> <script type="text/javascript"> // const set=new Set([1,2,3]); // console.log(...set);//1,2,3,使用擴展運算符 const set=new Set(document.querySelectorAll('div')); console.log(set.size);//5 size返回set實例的成員總數 //如上代碼至關於 const item=new Set(); document.querySelectorAll('div').forEach(x=>{ item.add(x); }) console.log(item); console.log(item.size);//5 </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>向set中添加成員時,不會發生類型轉換</title> </head> <body> <script type="text/javascript"> let mySet=new Set(); mySet.add(5); mySet.add('5'); console.log(mySet);//5,'5' let set=new Set(); let a=NaN; let b=NaN; set.add(a); set.add(b); console.log(set);//NaN </script> </body> </html>
向 Set 加入值的時候,不會發生類型轉換,因此5
和"5"
是兩個不一樣的值。Set 內部判斷兩個值是否不一樣,使用的算法叫作「Same-value-zero equality」,它相似於精確相等運算符(===
),主要的區別是向 Set 加入值時認爲NaN
等於自身,而精確相等運算符認爲NaN
不等於自身。java
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>向set中添加的對象老是不想等</title> </head> <body> <script type="text/javascript"> let set=new Set(); set.add({});//向set中添加一個空對象 console.log(set.size);//1 set.add({});//向set中添加另外一個空對象 console.log(set.size);//2 </script> </body> </html>
因爲兩個空對象不相等,因此它們被視爲兩個值es6
Array.from()能夠將set結構轉爲數組,這就提供了去除數組重複成員的另外一種方法算法
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Array.from()方法</title> </head> <body> <script type="text/javascript"> const items=new Set([1,2,3,4,5]); console.log(items);//1,2,3,4,5 const array=Array.from(items); console.log(array);//1.2.3,4,5 //Array.from()方法實現數組去重 function dedupe(arr){ return Array.from(new Set(arr)) } console.log(dedupe([1,1,2,3]));//1,2,3 </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>數組去重</title> </head> <body> <script type="text/javascript"> let set=new Set(['red','blue','green']); let arr=[...set]; console.log(arr);//red,blue,green //數組去重 let arrs=[1,1,3,3,4,5,6]; let unique=[...new Set(arrs)]; console.log(unique);//1,3,4,5,6 </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>間接使用數組的方法</title> </head> <body> <script type="text/javascript"> let set=new Set([1,2,3,4,5]); set=new Set([...set].map(x=>x*2));//使用數組的map方法 console.log(set);//2,4,6,8,10 let mySet=new Set([1,2,3,4,5]); mySet=new Set([...mySet].filter(x=>x%2==0));//使用數組的filter方法 console.log(mySet);//2,4 </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>實現並集,交集,差集</title> </head> <body> <script type="text/javascript"> let a=new Set([1,2,3]); let b=new Set([4,3,2]); //並集 let union=new Set([...a, ...b]); console.log(union);//1,2,3,4 //交集 let intersect=new Set([...a].filter(x=>b.has(x))); console.log(intersect);//2,3 //差集 let difference=new Set([...a].filter(x=>!b.has(x))); console.log(difference);//1 </script> </body> </html>
若是想在遍歷操做中,同步改變原來的 Set 結構,目前沒有直接的方法,但有兩種變通方法。一種是利用原 Set 結構映射出一個新的結構,而後賦值給原來的 Set 結構;另外一種是利用Array.from
方法。json
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>同步改變原來的 Set 結構</title> </head> <body> <script type="text/javascript"> //方法一 let set=new Set([1,2,3]); set=new Set([...set].map(val=>val*2)); console.log(set);//2,4,6 //方法二 let mySet=new Set([1,2,3]); mySet=new Set(Array.from(mySet,val=>val*2)); console.log(mySet);//2,4,6 </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>set中的size屬性</title> </head> <body> <script type="text/javascript"> const set=new Set(); //向set中添加成員 set.add(1); set.add(2); set.add(3); //鏈式方法 set.add(4).add(5).add(6); console.log(set.size);//6 </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>set中的操做方法add()、delete()、has()、clear()</title> </head> <body> <script type="text/javascript"> const set=new Set(); //向set中添加成員 set.add(1); set.add(2); set.add(3); //鏈式方法 set.add(4).add(5).add(6); console.log(set.size);//6 console.log(set.has(1));//true set.delete(1); console.log(set.has(1));//false set.clear();//清空所有set成員 console.log(set.size);//0 </script> </body> </html>
注意:set的遍歷順序就是插入順序,因爲set沒有鍵名,只有鍵值(或者說鍵名和鍵值是同一個值),因此keys()和values()方法的行爲徹底一致數組
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>set中的遍歷方法keys(),values(),entries(),forEach()</title> </head> <body> <script type="text/javascript"> let set=new Set(['red','blue','green']); //遍歷所有的key for(let key of set.keys()){ console.log(key);//red,blue,green } //遍歷所有的value for(let value of set.values()){ console.log(value);//red,blue,green } //遍歷所有的key和value for(let item of set.entries()){ console.log(item);//['red','red'],['blue','blue'],['green','green'] } set.forEach((key,value)=>{ console.log(key+':'+value); }) </script> </body> </html>
es6中的map很大程度上和set類似,可是map是以鍵值對的形式存儲數據的數據結構
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>map中的size屬性</title> </head> <body> <script type="text/javascript"> const map=new Map(); map.set('foo',true); map.set('bar',false); console.log(map.size);//2 </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>map中的set()方法</title> </head> <body> <script type="text/javascript"> const map=new Map(); map.set('1','a');//鍵是字符串 map.set(2,'b');//鍵是數值 map.set(undefined,'3');//鍵是undefined console.log(map);//'1'=>a,2=>b,undefinde=3 const myMap=new Map(); //鏈式寫法 myMap.set(1,'a').set(2,'b').set(3,'c'); console.log(myMap);//1=>a,2=>b,3=>c </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>map中的get()方法</title> </head> <body> <script type="text/javascript"> const map=new Map(); const hello=function(){ console.log('你好'); } map.set(hello,'es6');//鍵是函數 console.log(map.get(hello));//es6 </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>map中的has()方法</title> </head> <body> <script type="text/javascript"> const map=new Map(); //鏈式寫法 map.set('a',1).set('b',2).set('c',3);//向map中添加成員 console.log(map.has('a'));//true console.log(map.has('b'));//true console.log(map.has('c'));//true console.log(map.has('d'));//false </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>map中的delete方法</title> </head> <body> <script type="text/javascript"> const map=new Map(); map.set('a',1); console.log(map.has('a'));//true map.delete('a');//刪除鍵a console.log(map.has('a'));//false </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>map中的clear()方法</title> </head> <body> <script type="text/javascript"> const map=new Map(); map.set('foo',true);//向map中添加成員 map.set('bar',false); console.log(map.size);//2 map.clear();//清除map中的所有成員 console.log(map.size);//0 </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>遍歷方法keys(),values(),entries(),forEach()</title> </head> <body> <script type="text/javascript"> const map=new Map(); //向map中添加成員 map.set(1,'a'); map.set(2,'b'); map.set(3,'c'); //遍歷所有的鍵 for(let key of map.keys()){ console.log(key);//1,2,3 } //遍歷所有的值 for(let values of map.values()){ console.log(values);//a,b,c } //遍歷所有的鍵和值 for(let [key,value] of map.entries()){ console.log(key,value);//1=>a,2=>b,3=>c } for(let item of map.entries()){ console.log(item[0],item[1]);//1=>a,2=>b,3=>c } for(let [key,value] of map){ console.log(key,value);//1=>a,2=>b,3=>c } map.forEach(function(value,key){ console.log(key,value); }) </script> </body> </html>
注意:這裏的forEach()是值在前,鍵在後dom
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>map結構轉爲數組</title> </head> <body> <script type="text/javascript"> const map=new Map([ [1,'one'], [2,'two'], [3,'three'] ]); console.log([...map.keys()]);//[1,2,3] console.log([...map.values()]);//one,two,three console.log([...map]);//[1,one],[2,two],[3,three] console.log([...map.entries()]);//[1,one],[2,two],[3,three] const map1=new Map( [...map].filter(([key,value])=>key<3)//使用數組的filter方法 ); console.log(map1);//1=>one,2=>two </script> </body> </html>
做爲鍵值對存儲數據的map與其它數據也能夠進行轉換,咱們看下下面的案例函數
map轉爲數組最方便的方法,就是使用擴展運算符...
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Map轉爲數組</title> </head> <body> <script type="text/javascript"> const map=new Map();//建立map數據結構 map.set(true,7);//向map中添加成員 map.set({foo:3},['abc']); console.log([...map]);//[[true,7],[{foo:3},['abc']]]; </script> </body> </html>
將數組傳入map構造函數,就能夠轉爲map
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>數組轉爲map</title> </head> <body> <script type="text/javascript"> const map=new Map([ [true,7], [{foo:3},['abc']] ]); console.log(map); //map{ //true=>7, //object:{foo:3}=>['abc']; //} </script> </body> </html>
若是全部map的鍵都是字符串,它能夠無損的轉爲對象,若是有非字符串的鍵名,那麼這個鍵名會被轉爲字符串,再做爲對象的鍵名
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>map轉爲對象</title> </head> <body> <script type="text/javascript"> function strMapObj(strMap){ let obj=Object.create(null);//建立一個新對象 for(let [key,value] of strMap){//遍歷循環strMap obj[key]=value; } return obj; } const map=new Map().set('yes',true).set('no',false); console.log(strMapObj(map));//{yes:true,no:false} </script> </body> </html>
在這裏了我須要講解一下Object.create()這個方法,官方的意思是:Object.create()方法建立一個新對象,使用現有的對象來提供新建立的對象的__proto__
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>測試Object.create()方法</title> </head> <body> <script type="text/javascript"> const person={ isHuman: false, printIntroduction: function () { console.log(this.name,this.isHuman); } } const me = Object.create(person); me.name = "Matthew"; me.isHuman = true; me.printIntroduction();//Mattew,true </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>對象轉爲map</title> </head> <body> <script type="text/javascript"> function objToMap(obj){ let map=new Map(); for(let key of Object.keys(obj)){ map.set(key,obj[key]); } return map; } console.log(objToMap({yes:true,no:false}));//yes=>true,no=>false </script> </body> </html>
在這裏講解Object.keys()方法,官方解釋:Object.keys()
方法會返回一個由一個給定對象的自身可枚舉屬性組成的數組,數組中屬性名的排列順序和使用,for..in循環遍歷該對象時返回的順序一致 。若是對象的鍵-值都不可枚舉,那麼將返回由鍵組成的數組。
參數:要返回其枚舉自身屬性的對象
返回值:一個表示給定對象的全部可枚舉屬性的字符串數組
// simple array var arr = ['a', 'b', 'c']; console.log(Object.keys(arr)); // console: ['0', '1', '2'] // array like object var obj = { 0: 'a', 1: 'b', 2: 'c' }; console.log(Object.keys(obj)); // console: ['0', '1', '2'] // array like object with random key ordering var anObj = { 100: 'a', 2: 'b', 7: 'c' }; console.log(Object.keys(anObj)); // console: ['2', '7', '100'] // getFoo is a property which isn't enumerable var myObj = Object.create({}, { getFoo: { value: function () { return this.foo; } } }); myObj.foo = 1; console.log(Object.keys(myObj)); // console: ['foo']
map轉爲json要區分兩種狀況,一種狀況時map的鍵名都是字符串,這時能夠選擇轉爲對象json,另外一種狀況是map的鍵名有非字符串,這時能夠選擇轉爲數組json。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>map轉爲json</title> </head> <body> <script type="text/javascript"> function strMapToObj(strMap){ let obj=Object.create(null);//建立一個新對象 for(let [key,value] of strMap){ obj[key]=value; } return obj; } function strMapToJson(strMap){ return JSON.stringify(strMapToObj(strMap)); } let map=new Map().set('yes',true).set('no',false); let obj=strMapToJson(map); console.log(obj);//{'yes':true,'no':false} function mapToArrayJson(map){ return JSON.stringify([...map]); } let fooMap=new Map().set(true,7).set({foo:3},['abc']); let foo=mapToArrayJson(fooMap); console.log(foo);//[[true:7],[{foo:3},['abc']]] </script> </body> </html>
json轉爲map,正常狀況下全部鍵名都是字符串,可是有一種特殊狀況,整個json就是一個數組,且每一個數組成員自己,又是一個有兩個成員的數組,這時它能夠一一對應的轉爲map,這每每是map轉爲數組json的逆操做。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>json轉爲map</title> </head> <body> <script type="text/javascript"> function objTostrMap(obj){ let map=new Map(); for(let key of Object.keys(obj)){ map.set(key,obj[key]); } return map; } function jsonToStrMap(jsonStr){ return objTostrMap(JSON.parse(jsonStr)); } let obj1=jsonToStrMap('{"yes": true, "no": false}') console.log(obj1);//yes=>true,no=>false function jsonToMap(jsonStr){ return new Map(JSON.parse(jsonStr)); } let obj2=jsonToMap('[[true,7],[{"foo":3},["abc"]]]')//true=>7,{foo:3}=>['abc'] console.log(obj2); </script> </body> </html>
參考資料:http://es6.ruanyifeng.com/#docs/set-map
本章咱們主要學習了ES6中set和map相關的屬性和方法,set和map的方法中有不少都是相同的方法,has()、delete()、clear()、keys()、values()、entries、forEach()等等。