一、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方法。