Set与Map,告别重复与键值混乱

198 阅读3分钟

💡 从“暴力去重”到优雅数据管理

在做项目时,你是否也这样挣扎过?😣 用数组疯狂filter去重、拿对象硬怼非字符串键…直到遇见ES6的SetMap,我才发现:原来处理数据可以这么优雅!🚀 Set一键去重、Map自由键值,从此告别重复与混乱。这篇笔记,带你解锁高效数据操作的“真香”姿势!✨


Set:唯一值的魔法集合

1. 基本用法

Set 是ES6新增的数据结构,类似数组,但成员值唯一

const s = new Set();
[2, 3, 4, 5, 2, 2].forEach(x => s.add(x));
console.log([...s]); // [2, 3, 4, 5](自动去重!)

初始化直接传数组

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

2. 去重妙用

数组去重:一行代码搞定!

const arr = [2, 3, 4, 3, 2];
const uniqueArr = [...new Set(arr)]; // [2, 3, 4]

字符串去重

const str = "abbcddef";
const uniqueStr = [...new Set(str)].join(""); // "abcdef"

3. 注意事项

  • 严格相等判断5'5'算不同值。
  • 对象永不相等:即使是空对象!
const set = new Set();
set.add({}); set.add({});
console.log(set.size); // 2(两个空对象不相等!)

Map:键值对的终极进化

1. 与Object的差异

传统Object只能用字符串作为键,而Map支持任意类型键(对象、函数等)!

const map = new Map();
const objKey = { id: 1 };

map.set(objKey, "我是对象键的值");
map.set(123, "我是数字键的值");

console.log(map.get(objKey)); // "我是对象键的值"
console.log(map.get(123));    // "我是数字键的值"

2. 基本操作

增删改查

const map = new Map();
map.set("name", "小明");  // 添加键值对
console.log(map.has("name")); // true
console.log(map.get("name")); // "小明"
map.delete("name");        // 删除
map.clear();               // 清空

3. 键的引用特性

Map的键与内存地址绑定,只有同一引用才视为相同键!

const map = new Map();
const k1 = ["a"];
const k2 = ["a"];

map.set(k1, 100);
map.set(k2, 200);
console.log(map.get(k1)); // 100(k1和k2内存地址不同!)

WeakSet与WeakMap:低调的“弱引用”兄弟

1. 特性

  • 弱引用:不阻止垃圾回收,适合临时存储。
  • 键必须是对象(WeakMap的键)。
  • 不可遍历

2. 使用场景

WeakMap存储私有数据

const privateData = new WeakMap();

class User {
  constructor(name) {
    privateData.set(this, { name }); // this作为键,外部无法访问
  }
  getName() {
    return privateData.get(this).name;
  }
}

const user = new User("小明");
console.log(user.getName()); // "小明"

实战:Set和Map的高阶玩法

1. 集合运算(并集、交集、差集)

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

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

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

// 差集(a有但b无)
const difference = new Set([...a].filter(x => !b.has(x))); // {1}

2. Map与其他数据结构的转换

Map转数组

const map = new Map().set("a", 1).set("b", 2);
const arr = [...map]; // [["a", 1], ["b", 2]]

对象转Map

function objToMap(obj) {
  return new Map(Object.entries(obj));
}
const map = objToMap({ yes: true, no: false });

总结

ES6的SetMap彻底改变了JS数据处理方式!✨ Set凭借成员唯一性,轻松实现数组/字符串去重,还支持并集、交集等集合运算;Map则以任意类型为键(甚至对象!),成为比Object更强大的字典工具。它们的“弱引用”兄弟——WeakSetWeakMap,通过不干扰垃圾回收,完美解决内存泄漏问题,适合存储临时数据。无论是消灭重复值、管理复杂键值对,还是优化内存,SetMap都是前端高效开发的秘密武器!🚀

💡 学习感悟:以前用数组和Object硬扛,现在用Set和Map真香!尤其适合处理数据唯一性和键值灵活性需求~