📈「作者简介」:不知名十八线技术博主【ai_todo】
📚「推荐主页」:前端小姐姐【阿珊和她的猫】
🎁「推荐专栏」:《从0到0.01入门React》
🕐「简历必备」前后端实战项目(推荐:⭐️⭐️⭐️⭐️⭐️)
当谈到集合和映射数据结构时,JavaScript提供了四种不同的内建对象:Set、Map、WeakSet和WeakMap。它们具有不同的特点和用途。
1. Set(集合)
- Set对象允许存储任何类型的唯一值,不允许重复。
- Set中的值是无序的,无法通过索引访问。
- 通过
add()
方法添加值到Set中,通过has()
方法检查值是否存在,通过delete()
方法删除值。 - 可以使用
size
属性获取Set中的值的数量。 - Set是迭代器,可以使用
forEach()
或for...of
循环遍历Set中的值。
当使用Set(集合)时,你可以执行以下操作的示例代码:
- 创建一个空的Set:
const set = new Set();
- 向Set中添加值:
set.add("apple");
set.add("banana");
set.add("orange");
- 检查值是否存在于Set中:
console.log(set.has("apple")); // 输出: true
console.log(set.has("grape")); // 输出: false
- 从Set中删除值:
set.delete("banana");
console.log(set); // 输出: Set { "apple", "orange" }
- 获取Set的大小:
console.log(set.size); // 输出: 2
- 遍历Set中的值:
set.forEach(value => {
console.log(value);
});
// 输出:
// apple
// orange
// 或者使用for...of循环
for (const value of set) {
console.log(value);
}
// 输出:
// apple
// orange
请注意,Set中存储的值是唯一的,重复的值将被忽略。此外,Set是无序的,无法通过索引进行访问。
2. Map(映射)
- Map对象是键值对的集合,与对象不同的是,键可以是任何数据类型。
- Map中的键值对是有序的。
- 通过
set()
方法设置键值对,通过get()
方法获取值,通过has()
方法检查键是否存在,通过delete()
方法删除键值对。 - 可以使用
size
属性获取Map中键值对的数量。 - Map也是迭代器,可以使用
forEach()
或for...of
循环遍历键值对。
当使用Map(映射)时,你可以执行以下操作的示例代码:
- 创建一个空的Map:
const map = new Map();
- 向Map中添加键值对:
map.set("apple", 10);
map.set("banana", 5);
map.set("orange", 8);
- 获取键对应的值:
console.log(map.get("apple")); // 输出: 10
console.log(map.get("grape")); // 输出: undefined
- 检查键是否存在于Map中:
console.log(map.has("apple")); // 输出: true
console.log(map.has("grape")); // 输出: false
- 从Map中删除键值对:
map.delete("banana");
console.log(map); // 输出: Map { "apple" => 10, "orange" => 8 }
- 获取Map的大小:
console.log(map.size); // 输出: 2
- 遍历Map中的键值对:
map.forEach((value, key) => {
console.log(key, value);
});
// 输出:
// apple 10
// orange 8
// 或者使用for...of循环
for (const [key, value] of map) {
console.log(key, value);
}
// 输出:
// apple 10
// orange 8
请注意,与Set不同,Map中的键可以是任何数据类型,而不仅限于字符串。此外,Map中的键值对是有序的。
3. WeakSet(弱引用集合)
- WeakSet对象中存储对象的弱引用,而不是对实际对象的引用。
- WeakSet中的对象是无序的,无法通过索引访问。
- 由于使用弱引用,当没有其他引用指向对象时,垃圾回收机制会自动删除WeakSet中的对象。
- WeakSet没有提供遍历的方法。
使用WeakSet(弱引用集合)时,你可以执行以下操作的示例代码:
- 创建一个空的WeakSet:
const weakSet = new WeakSet();
- 向WeakSet中添加对象:
const obj1 = { name: "Alice" };
const obj2 = { name: "Bob" };
const obj3 = { name: "Charlie" };
weakSet.add(obj1);
weakSet.add(obj2);
weakSet.add(obj3);
- 检查对象是否存在于WeakSet中:
console.log(weakSet.has(obj1)); // 输出: true
console.log(weakSet.has(obj2)); // 输出: true
console.log(weakSet.has(obj3)); // 输出: true
const obj4 = { name: "Dave" };
console.log(weakSet.has(obj4)); // 输出: false
- 从WeakSet中删除对象:
weakSet.delete(obj2);
console.log(weakSet.has(obj2)); // 输出: false
请注意,在没有其他引用指向对象时,即使该对象存在于WeakSet中,垃圾回收机制也会自动删除该对象。因此,无法获取WeakSet的大小也无法遍历其中的对象。WeakSet主要用于存储临时对象,例如在特定操作期间需要跟踪的对象。
4. WeakMap(弱引用映射)
- WeakMap对象是键值对的集合,与Map不同的是,键必须是对象。
- WeakMap中的键值对是无序的。
- 使用弱引用的键意味着当没有其他引用指向键时,垃圾回收机制会自动删除WeakMap中的键值对。
- WeakMap没有提供遍历的方法。
使用WeakMap(弱引用映射)时,你可以执行以下操作的示例代码:
- 创建一个空的WeakMap:
const weakMap = new WeakMap();
- 向WeakMap中添加键值对:
const obj1 = { name: "Alice" };
const obj2 = { name: "Bob" };
const obj3 = { name: "Charlie" };
weakMap.set(obj1, 10);
weakMap.set(obj2, 5);
weakMap.set(obj3, 8);
- 获取键对应的值:
console.log(weakMap.get(obj1)); // 输出: 10
console.log(weakMap.get(obj2)); // 输出: 5
console.log(weakMap.get(obj3)); // 输出: 8
const obj4 = { name: "Dave" };
console.log(weakMap.get(obj4)); // 输出: undefined
- 检查键是否存在于WeakMap中:
console.log(weakMap.has(obj1)); // 输出: true
console.log(weakMap.has(obj2)); // 输出: true
console.log(weakMap.has(obj3)); // 输出: true
const obj4 = { name: "Dave" };
console.log(weakMap.has(obj4)); // 输出: false
- 从WeakMap中删除键值对:
weakMap.delete(obj2);
console.log(weakMap.has(obj2)); // 输出: false
请注意,与WeakSet一样,当没有其他引用指向键时,即使键存在于WeakMap中,垃圾回收机制也会自动删除该键及其对应的值。由于WeakMap的键必须是对象,因此无法获取WeakMap的大小,也无法遍历其中的键值对。WeakMap通常用于存储附加数据,而无需担心内存泄漏或手动清除数据。
需要注意的是,WeakSet
和WeakMap
是弱引用结构,意味着在内存管理方面更加灵活,但也会带来一些限制。它们不能被迭代,也不能直接获取其大小。此外,WeakSet和WeakMap不是可枚举的,不能使用forEach()
和for...of
循环来遍历其中的值或键值对。