【ES6】Set 和 Map 数据结构

文章目录

  • 前言
  • 一、Set
    • 1. 用法详解
      • 1.1 声明方式
      • 1.2 遍历的四种方式
    • 2. 应用场景
      • 2.1 数组去重
      • 2.2 合并去重
      • 2.3交集
      • 2.4 差集
    • 3. WeakSet
  • 二、Map
    • 1. 用法详解
      • 1.1 声明方式
      • 1.2 遍历的四种方式
    • 2. 应用场景
    • 3. WeakMap
  • 总结


前言

Set 、 Map为ES6新增的数据结构。


一、Set

ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
Set 本身是一个构造函数,用来生成 Set 数据结构。

1. 用法详解

1.1 声明方式

// 声明方式
let s = new Set()
console.log(s)

//唯一的
let s = new Set([1, 2, 3, 2])
// 添加新的值
s.add('kaka').add('Dorothy') // 支持链式操作
// s.delete(2) // 删除2
// s.clear() // 清空
console.log(s.has('kaka')) //true,判断是否包含某个值
console.log(s) // 1 2 3 kaka Dorothy
console.log(s.size) // 输出Set的长度

1.2 遍历的四种方式

  • keys() :返回键名的遍历器
  • values() :返回键值的遍历器
  • entries() :返回键值对的遍历器
  • forEach():使用回调函数遍历每个成员
s.forEach(item => console.log(item))

for (let item of s) {
    console.log(item)
}
for (let item of s.keys()) {
    console.log(item)
}
for (let item of s.values()) {
    console.log(item)
}
for (let item of s.entries()) {
    console.log(item[0], item[1])
    //1 1
    //2 2
    //3 3
    //kaka kaka
    //Dorothy Dorothy
}

Set相当于也有key:value,只不过它的key和value是相同的。

2. 应用场景

2.1 数组去重

let arr = [1, 2, 3, 4, 2, 3]
let s = new Set(arr)
console.log(s)

2.2 合并去重

let arr1 = [1, 2, 3, 4]
let arr2 = [2, 3, 4, 5, 6]
let s = new Set([...arr1, ...arr2])
console.log(s)
// {1, 2, 3, 4, 5, 6}

// set->array
console.log([...s])
console.log(Array.from(s))
//[1, 2, 3, 4, 5, 6]

2.3交集

let s1 = new Set(arr1)
let s2 = new Set(arr2)
let result = new Set(arr1.filter(item => s2.has(item)))
//{2, 3, 4}
console.log(Array.from(result))
//[2, 3, 4]

2.4 差集

let arr3 = new Set(arr1.filter(item => !s2.has(item)))
let arr4 = new Set(arr2.filter(item => !s1.has(item)))
console.log(arr3)
//{1}
console.log(arr4)
//{5, 6}
console.log([...arr3, ...arr4])
//[1, 5, 6]

3. WeakSet

WeakSet只能够存储对象(与Set的区别1),数字、字符串等原始数据对象不能够放进去。WeakSet不能够遍历区别2)。

let ws = new WeakSet()
const obj1 = {
    name: 'kaka'
}
const obj2 = {
    age: 5
}
ws.add(obj1)
ws.add(obj2)
// 删除对象
ws.delete(obj1)
console.log(ws)
//仅剩obj2

console.log(ws.has(obj2))
//true

ws.forEach(item => console.log(item))
//报错

垃圾回收机制:GC +1 +1,只要GC后面的值不为0,则不会被回收,所以可能会有内存泄漏的风险。
WeakSet 的对象是弱引用,它不会被计入垃圾回收机制区别3),所以不管它是否还有引用,当前使用完之后便回收了,可用于临时存放对象。

二、Map

JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。为了解决这个问题,ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以 当作键。也就是说,Object 结构提供了“字符串-值”的对应,Map 结构提供了“值-值”的对应,是一种更完善的 Hash 结构实现。如果需要“键值 对”的数据结构,Map 比 Object 更合适。

1. 用法详解

1.1 声明方式

let m = new Map()
let obj = { 
    name: 'kaka'
}
// set添加新的值 key:value
m.set(obj, 'es')
console.log(m)
// 输出整个Map
// get获取值
console.log(m.get(obj)) // es
// 删除
m.delete(obj)
// 判断是否包含当前这个key对应的值
console.log(m.has(obj))

将数组作为参数:

// 将数组作为参数
let map = new Map([
    ['name', 'kaka'],
    ['age', 5]
])
console.log(map.size)
// 2
console.log(map.has('name')) // true
console.log(map.get('age')) // 5
map.set('name', 'wengweng') // "name" => "wengweng"
map.delete('name') // 删除
map.clear() // 清空
console.log(map)

1.2 遍历的四种方式

  • keys() :返回键名的遍历器
  • values() :返回键值的遍历器
  • entries() :返回键值对的遍历器
  • forEach():使用回调函数遍历每个成员(注意:forEach遍历方式传递的参数是(value, key)的形式,值在前键在后

与Set的区别是,Set的key和value是相同的,而Map的不同。

//遍历
map.forEach((value, key) => console.log(value, key))

for(let [key, value] of map){
    console.log(key, value)
}

for(let key of map.keys()){
    console.log(key)
}

for(let value of map.values()){
    console.log(value)
}

for(let [key, value] of map.entries()){
    console.log(key, value)
}

与Object比较:
① Map判断是否包含某个属性时可直接调用.has(),而Object需要循环遍历才能够判断,所以Map的api更加灵活。
② Map的key更多样。
③ Map可直接通过.size()来获取键值对的个数,而Object仍需要循环。
④ Object含有自己的原型,原型链上的名字与自己定义的键名可能会冲突。

2. 应用场景

使用Object的场景都可考虑使用Map。

3. WeakMap

WeakMap与Map的结构相似,不同点在于:WeakMap的键名(key)仅支持引用数据类型(对象、数组、函数),且WeakMap不支持遍历,也是一种弱引用,不会被计入垃圾回收机制。

let wm = new WeakMap()
wm.set([1], 2)
wm.set({
    name: 'kaka'
}, 'es')
// WeakMap不支持clear清空
wm.clear() // 报错
// WeakMap不支持size方法(因为也涉及到遍历)
console.log(wm.size) // undefined

// 应用场景
let wm = new WeakMap()
let elem = document.getElementsByTagName('h1')
wm.set(elem, 'info')
console.log(wm.get(elem))

总结

Set相对于数组(Array)
Map相对于对象(Object)

你可能感兴趣的:(ES6,javascript,数据结构,前端)