一、set
1.es6新数据结构。特点是元素值唯一(键值相等)、会主动去重。判断方法是 ‘值相等’ 原则,不进行隐式转化,NaN与自身相等(类似Object.is)。
set构造函数,接受一个具有iterator接口的数据结构作为参数如array、map、set、类数组(domlist、arguments、string,map),否则会报错。
set.size表示集合元素个数(类似于数组length属性)
let mySet = new Set('123123abcabc');console.log(mySet)// => Set(6) {"1", "2", "3", "a", "b", …}[[Entries]]0: "1"1: "2"2: "3"3: "a"4: "b"5: "c"size: 6
2.用处:<br />(1)数组去重(**可以对两个NAN去重**)
let arr = [1,1,2,2,'a','a','b','b'];function unique (arr){return Array.from(new Set(arr))}console.log(unique(arr)) // => [1, 2, "a", "b"]
(2)字符串去重
let str ='112233445566';function uniqueStr (str){return [... new Set(str)].join('')}console.log(uniqueStr(str))
3.set原型方法<br />(1)set.prototype.add 添加新元素<br />(2)set.prototype.delete 删除元素,返回boolean表示删除是否成功<br />(3)set.prototype.has 判断是否包含元素,赶回boolean<br />(4)set.prototype.clear 清空所有元素,没有返回值<br />set结构只有增删、判断有无、清空的功能。没有直接改的功能。<br />4.set遍历方法<br />(1)set.keys 和set.values返回相同元素值的遍历器iterator<br />(2)set.entries 返回二维数组,数组中包含两个相同的值(set的键与值相同)<br />(3)set.forEach 和数组的forEach相同,接受一个两个参数,第一个为callback函数,第二个为函数中的this值。<br />set遍历方法中不能改变原数据,只能重新赋值。数组想要删除的话,用split方法。
let set = new Set([1,2,3]);function changeSet(set1){let newSet = new Set([...set1].map(item => item * 2));console.log(set, newSet)set = newSet}changeSet(set)console.log(set) // 给形参重新赋值不会影响外部变量,修改形参会因为共享数据而影响外界
5.set结构转化为数组后可以使用map、filter等方法,所以能够很方便地得出两个数据结构的并集(union)、交集(intersect)、差集(difference)
let set1 = new Set('123abc'),set2 = new Set('136acf');let union = new Set([...set1,...set2]),intersect = new Set([...set1].filter(item => set2.has(item))),difference = new Set([...set1].filter(item => !set2.has(item)));console.log(union, intersect, difference)
二、weakSet
weakSet也是元素唯一的数据结构,但是元素必须是对象,传对象会报错。
let set = new weakSet([{name:'weakSet'}]);
weakSet有add、has、delete方法。没有clear方法。<br />** weakSet对对象是弱引用**,**不会被垃圾回收机制考虑**,也就是,如果外部不再引用weakSet中的对象,那么该对象会被垃圾回收机制清理。<br />weakSet没有size属性,因为里面的对象随时都可能消失。所以不能进行遍历。<br />用处:<br />(1)weakSet可以用来保存dom节点,在dom从文档中删除后,不用担心内存泄漏。<br />(2)给原型添加只能由实例调用的方法
let setWeak = new weakSet()class weakSetFun {constructor(){setWeak.add(this)}foo(){let isInstance = setWeak.has(this);if(isInstance){console.log('function called')}else{throw new Error('only instance can call this function')}}}
三、map
1、基本概念、用法
js中,object是一种’键值对’的集合,键名只能为字符串,es6中Map突破了这一种束缚,接受任意类型作为键名。
Map构造函数中接受部署Iterator接口的数据结构(array, set, map, nodeList, arguments等),且每个元素为包含两个元素的数组,否则会报错(Iterator value xxx is not an entry object)。
let myMap = new Map([ [[], 'array',], [123, [5,6,7]]]);console.log(myMap)let set1 = new Set([[[], 1], [[], 2]]),map1 = new Map(set1);console.log(map1)
map有get、set、delete、clear方法用于存取删除清空元素。
map.size属性表示,储存元素个数。
map结构中,键名的重复性判断是值相等,不进行隐式转化( set结构,find,findIndex,includes都是值相等判断,NaN等于自身,0 等于-0 ),如果是引用值,map会判断其引用指针。
let o = {name:'obj'},myMap = new Map();myMap.set(o, 'name');console.log(myMap.get(o), myMap.size)//属性重名会覆盖myMap.set(NaN,'1')myMap.set(NaN,'6')console.log(myMap.get(NaN)) // => '6'//map判断键名引用值let map2 = new Map();map2.set(['a'], 1)console.log(map2.get(['a'])) // => undefined
用引用值设置键名,这样就解决了同名属性冲突的问题,在拓展别人的插件时很管用。
2、map的遍历
map的遍历顺序就是元素插入顺序,而object是一种无序的键值对集合,es6中新增了有序键值对集合,所以给object部署iterator就没有啥必要了。
map.keys 返回map元素所有键的迭代器
map.values 返回map元素所有值的迭代器
map.entries 返回一个二维数组,每个元素为一个数组,包含了一对键值对元素。
map.forEach 遍历map的方法
let map = new Map([['1', 1], ['abc', 123]]);map.forEach((value, key, mapObj)=>{// 回调函数中形参顺序为value, key, map, 与array的forEach一样value, index, array,//array的index就是元素的key值console.log(value, key, mapObj)},null)
map.entries返回的结构与map[Symbol.iterator]一样,两者相等。
let map = new Map([['1', 1], ['abc', 123]]);let mapEntiresIterator = map.entries();console.log(mapEntiresIterator)console.log(mapEntiresIterator.next())// => {value: ['1', 1], done: false} value是当前遍历的元素,不是元素的value值for(let [k, v] of mapEntiresIterator){console.log(k, v) // => 'abc', 123}
map转换为数组: 拓展运算,转化后就可以用数组的map、filter等方法了。<br />过滤map中值小于6的元素。
let map = new Map([[{name:123}, 6], [[],[1]]]);function transform(map){let newMap = new Map([...map].filter((item)=> item[1] < 6));return newMap}map = transform(map)console.log(map)
四、weakMap
是一种特殊的map结构,只接受键名为对象元素,对键名元素对象的引用为弱引用,对键值对象为正常引用。
weakMap的专用场合就是,防止内存泄漏,适合将dom节点拿来作为元素的键名,如果文档中dom节点被删除,weakMap中对应的键名和键值就会自动消失。
weakMap和weakSet一样,元素随时可能消失,所以没有size属性,没有forEach方法。
