「这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战」。
一、Set
1.1 概念及声明
-
set是ES6新增的一种数据结构-集合。set对象是值得集合,它里面的的元素是惟一的。
-
声明方式
let s = new Set()
console.log(s) //set(0){size=0}
let s = new Set([1,2,3])
console.log(s) //set(3) {1,2,3}
- 里面的元素是惟一的
let arr = [1,2,3,3,3]
let s = new Set(arr)
console.log(s)//set(3) {1,2,3}
1.2 set的方法
- add 增加元素
let arr = [1,2,3]
let s = new Set(arr)
s.add(4)
console.log(s) //set(4) {1,2,3,4}
- delete 删除元素
let arr = [1,2,3]
let s = new Set(arr)
s.delete(1)
console.log(s) //set(2) {2,3}
- has 判断是否含有
let arr = [1,2,3]
let s = new Set(arr)
console.log(s.has(1))
- clear 清空set对象
let arr = [1,2,3]
let s = new Set(arr)
s.clear()
console.log(s) //set(0){size=0}
- size set元素的个数
let arr = [1,2,3]
let s = new Set(arr)
console.log(s.size)
1.3 set的遍历方式
let arr = [1,2,3,'hello','world']
let s = new Set(arr)
- forEach
s.forEach(item => {
console.log(item) //1 2 3 hello world
})
- for of
for(let item of s) {
console.log(item) //1 2 3 hello world
}
for(let item of s.keys()) {
console.log(item) //1 2 3 hello world
}
for(let item of s.values()) {
console.log(item) //1 2 3 hello world
}
需要注意的是,key和value的值是完全一样的
for(let item of s.entries()) {
console.log(item[0],item[1]) //1 2 3 hello world
//1 2 3 hello world
}
1.4 数组去重
利用Set的元素是惟一的特性进行去重
let arr = [1,2,3,2,3]
let s = new Set(arr)
console.log(s);
1.5 数组合并去重
let arr = [1,2,3,2,3]
let arr1 = [2,3,4,5,6,3]
let s = new Set([...arr, ...arr1])
console.log(s) //{1,2,3,4,5,6}
上述得出的结果仍为对象,我们可以将其转换为数组
console.log([...s]) //[1, 2, 3, 4, 5, 6]
console.log(Array.from(s)) //[1, 2, 3, 4, 5, 6]
1.6求交集
let arr1 = [1,2,3,2,3]
let arr2 = [2,3,4,5,6,3]
let s2 = new Set(arr2)
let s = new Set(arr1.filter(item => s2.has(item)))
console.log(s) //{2,3}
1.7 求差集
这里需要注意的是在filter的arr1对应的是s2,arr2对应的是s1。很多同学搞反了,导致最后没有值。
let arr1 = [1,2,3,2,3]
let arr2 = [2,3,4,5,6,3]
let s1 = new Set(arr1)
let s2 = new Set(arr2)
let res1 = new Set(arr1.filter(item => !s2.has(item)))
let res2 = new Set(arr2.filter(item => !s1.has(item)))
console.log([...res1,...res2]) // [1, 4, 5, 6]
二、WeakSet
2.1 概念及声明方式
-
WeakSet将弱保持对象存储在一个集合中
-
声明方式
let ws = new WeakSet()
console.log(ws) //WeakSet {}
需要注意的是,WeakSet的参数只能是一个可迭代对象,不能是其它任何值。这是与Set的不同点之一。
let ws = new WeakSet(1) //报错 number 1 is not iterable
2.2 方法
- add add的参数也只能是一个对象
let ws = new WeakSet()
ws.add({name: '张三'})
- delete 可以想一下,下面这种情况,能删除成功么?
let ws = new WeakSet()
ws.add({name: '张三'})
ws.delete({name: '张三'})
很显然是不会成功的,因为对象是引用类型,引用类型存储在对内存中,两个{name: '张三'}对应的是两个不同的内存空间。所以上述方法不会成功。以下方法可以成功删除
let ws = new WeakSet()
let obj = {
name: '张三'
}
ws.add(obj)
ws.delete(obj)
console.log(ws);
- has 参数也只能是对象
let ws = new WeakSet()
let obj = {
name: '张三'
}
ws.add(obj)
console.log(ws.has(obj));
2.3 不可遍历
WeakSet是不可以遍历的。因为其内部有多少个元素完全是不可控制的,这取决于垃圾回收机制的运行时机。而垃圾回收机制的运行时机同样也是不可预测的。所以没有办法遍历。
2.4 弱引用
WeakSet的对象都是弱引用,也就是说随时可以被垃圾回收机制回收,适合存放一组对象以及存放跟对象绑定的值。主要用于防止内存泄漏。
三、Set和WeakSet的区别
- Set可以遍历,WeakSet则不可以
- WeakSet是弱引用,Set是强引用
- WeakSet的参数只能是一个可迭代的对象
四、如何判断是否是可迭代对象
判断一个对象是否可迭代,就检测它是否具有Symbol.iterator属性
Array.prototype.hasOwnProperty(Symbol.iterator)
Symbol.iterator是一个函数,可以通过typeOf来检测,返回function则是可迭代对象,返回undefined则不是
const a = [[1,2],[3,4]];
console.log(typeof a[Symbol.iterator]) //function
五、map
5.1 意义及声明方式
- map对象保存键值对,并能够记住键的原始插入顺序。任何值都可以作为键或值
- 声明方式
let m =new Map()
5.2 方法
- set
let m =new Map()
m.set('name','张三')
console.log(m) // {'name' => '张三'}
- get
let m =new Map()
m.set('name','张三')
console.log(m.get('name')) // 张三
- delete
let m =new Map()
m.set('name','张三')
m.delete('name')
console.log(m) // Map(0) {size: 0}
- has
let m =new Map()
m.set('name','张三')
console.log(m.has('name')) // true
- size
et m =new Map()
m.set('name','张三')
console.log(m.size) // 1
5.3 遍历方式
let obj = {
name: '张三',
age: 5
}
let m = new Map(obj)
- forEach
m.forEach((v,k) => {
console.log(k,v);
})
- for of keys values同样适用
for(let [k,v] of m.entries()){
console.log(k,v)
}
六、Map和WeakMap区别
- Map的键可以是任意值,WeakMap的键只能是对象
- WeakMap是弱引用
- WeakMap不可被遍历