ES6-11第八天-set和map

128 阅读4分钟

「这是我参与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 求差集

这里需要注意的是在filterarr1对应的是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不可被遍历