浅析 Map、Set 类型

Map

简介

Map 数据结构类似于 JavaScript 中的对象,不过对象的键只能是字符串, Map 的键可以是任意类型的值。需要注意的是,Map 的键是跟内存地址绑定的,因此有些看似相同的键,值却是不一样的,这一点会在下文举例说明。

Map 的键和内存地址绑定带来的好处是避免了同名属性碰撞/冲突问题,因此我们在对别人的库进行扩展时,不用担心会破坏原本的值。

Map 可以接受一个数组作为参数,但该数组的成员需要是一个个表示键值对的数组。

const map = new Map([
  ['name', '张三'],
  ['age', '18']
]);
// {'name': '张三', 'age': '18'}

操作方法

map.has('name') // 判断是否存在某个键,返回true/false
map.get('name') // 获取某个键的值,如果不存在,则返回 undefined
map.set('sex', '男') // 添加成员,如果添加重复的键,会覆盖已存在的值
map.delete('sex') // 删除某个值,成功返回 true,失败返回 false

Map 的键是和内存绑定的,这一点要尤其注意。仔细观察下面的两组示例:

必须严格等于的两个值,Map 才会将它们视为同一个键,NaN 除外。

const map = new Map();

map.set(['a'], 666);
map.get(['a']) // undefined
const map = new Map();
const a = ['a']

map.set(a, 666);
map.get(a) // 666

遍历

Map 也可以像数组一样遍历,但是操作方法有所区别,只能用 keys()values()entries()forEach() 等方法来遍历。默认遍历器接口是 entries

const map = new Map([
  ['name', '张三'],
  ['age', '18']
]);

for (let item of map.keys()) {
    
    
  console.log(item);
}
// 'name'
// 'age'

for (let item of map.values()) {
    
    
  console.log(item);
}
// '张三'
// '18'

for (let item of map.entries()) {
    
    
  console.log(item);
}
// ['name', '张三']
// ['age', '18']

for (let [key, value] of map.entries()) {
    
    
  console.log(key, value);
}
// 'name' '张三'
// 'age' '18'

for (let [key, value] of map) {
    
    
  console.log(key, value);
}
// 'name' '张三'
// 'age' '18'

map.forEach(function(value, key, map) {
    
    });

WeakMap

简介

WeakMapMap 类似,不过键只能是对象或者 null,不可以是其它类型,同时,WeakMap 中的成员是弱引用,不影响垃圾回收机制。

Set

简介

SetES6 提供的一种新的数据结构,,类似于数组结构,它的键和值是同一个,且它的值都是唯一且不重复的。

Set 本身是一个构造函数,用来生成 Set 数据结构。向 Set 添加值的时候,被添加的值类型不会发生改变。

Set 可以接受一个数组作为参数来进行初始化。

const set = new Set([1, 2, 3, 4, 4, 4]);
[...set] // [1, 2, 3, 4]

添加成员

可以通过 add() 方法向 Set 添加成员,注意,无法添加重复的成员。

const set = new Set([1, 2, 3, 4, 4, 4]);

set.add(1) // {1, 2, 3, 4}
set.add(5) // {1, 2, 3, 4, 5}

修改成员

Set 本身没有方法修改成员,但是可以通过其它途径来进行修改,比如映射一个新的 Set 。

let set = new Set([1, 2, 3]);
set = new Set([...set].map(val => val * 2));
// {2, 4, 6}

操作方法

Set 的一些其它方法。

const set = new Set([1, 2, 3, 4, 4, 4]);

set.add(5) // 添加成员
set.delete(1) // 删除成员
set.has(5) // 判断成员是否存在,返回 true/false
set.clear() // 清空所有成员

遍历

Set 也可以像数组一样遍历,但是操作方法有所区别,只能用 keys()values()entries()forEach() 等方法来遍历。

const set = new Set([1, 2, 3]);

for (let item of set.keys()) {
    
    
  console.log(item);
}
// 1
// 2
// 3

for (let item of set.values()) {
    
    
  console.log(item);
}
// 1
// 2
// 3

for (let item of set.entries()) {
    
    
  console.log(item);
}
// [1, 1]
// [2, 2]
// [3, 3]

set.forEach((value, key) => console.log(key + ' : ' + value))
// 1 : 1
// 2 : 2
// 3 : 3

交集、并集、差集

利用遍历及 Set 数据类型不会有重复值的特性,可以轻松获取交集、并集、差集。

const a = new Set([1, 2, 3]);
const b = new Set([3, 4, 5]);

// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// set {3}

// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4, 5}

// 差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1, 2, 4, 5}

WeakSet

简介

WeakSet 类似于 Set ,也是不重复的值的集合,但是 WeakSet 的值只能是对象(非对象会报错),且 WeakSet 中的对象都是弱引用。

垃圾回收机制不会考虑 WeakSet 对对象的引用,如果没有其它地方存在对 WeakSet 中的对象引用,那么垃圾回收就会清理掉 WeakSet 中的对象。

const ws = new WeakSet([[1, 2], [3, 4]]);
// {[1, 2], [3, 4]}

操作方法

const ws = new WeakSet();
const obj = {
    
    };

ws.add(obj) // 添加成员
ws.delete(obj) // 删除成员
ws.has(obj) // 判断成员是否存在,返回 true/false

注意:WeakSet 无法遍历。

END

猜你喜欢

转载自blog.csdn.net/m0_53808238/article/details/131230468