深入解析: Set、Map、WeakSet 和 WeakMap 的区别

深入解析: Set、Map、WeakSet 和 WeakMap 的区别_第1张图片

文章目录

    • 1. Set(集合)
    • 2. Map(映射)
    • 3. WeakSet(弱引用集合)
    • 4. WeakMap(弱引用映射)
    • 附录:「简历必备」前后端实战项目(推荐:⭐️⭐️⭐️⭐️⭐️)

「作者简介」:不知名十八线技术博主【ai_todo】
「推荐主页」:前端小姐姐【阿珊和她的猫】
「推荐专栏」:《从0到0.01入门React》
「简历必备」前后端实战项目(推荐:⭐️⭐️⭐️⭐️⭐️)

  • Vue.js 和 Egg.js 开发企业级健康管理项目
  • 带你从入门到实战全面掌握 uni-app

当谈到集合和映射数据结构时,JavaScript提供了四种不同的内建对象:Set、Map、WeakSet和WeakMap。它们具有不同的特点和用途。

1. Set(集合)

  • Set对象允许存储任何类型的唯一值,不允许重复。
  • Set中的值是无序的,无法通过索引访问。
  • 通过add()方法添加值到Set中,通过has()方法检查值是否存在,通过delete()方法删除值。
  • 可以使用size属性获取Set中的值的数量。
  • Set是迭代器,可以使用forEach()for...of循环遍历Set中的值。

当使用Set(集合)时,你可以执行以下操作的示例代码:

  1. 创建一个空的Set:
const set = new Set();
  1. 向Set中添加值:
set.add("apple");
set.add("banana");
set.add("orange");
  1. 检查值是否存在于Set中:
console.log(set.has("apple"));     // 输出: true
console.log(set.has("grape"));     // 输出: false
  1. 从Set中删除值:
set.delete("banana");
console.log(set);                  // 输出: Set { "apple", "orange" }
  1. 获取Set的大小:
console.log(set.size);             // 输出: 2
  1. 遍历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(映射)时,你可以执行以下操作的示例代码:

  1. 创建一个空的Map:
const map = new Map();
  1. 向Map中添加键值对:
map.set("apple", 10);
map.set("banana", 5);
map.set("orange", 8);
  1. 获取键对应的值:
console.log(map.get("apple"));    // 输出: 10
console.log(map.get("grape"));    // 输出: undefined
  1. 检查键是否存在于Map中:
console.log(map.has("apple"));    // 输出: true
console.log(map.has("grape"));    // 输出: false
  1. 从Map中删除键值对:
map.delete("banana");
console.log(map);                 // 输出: Map { "apple" => 10, "orange" => 8 }
  1. 获取Map的大小:
console.log(map.size);            // 输出: 2
  1. 遍历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(弱引用集合)时,你可以执行以下操作的示例代码:

  1. 创建一个空的WeakSet:
const weakSet = new WeakSet();
  1. 向WeakSet中添加对象:
const obj1 = { name: "Alice" };
const obj2 = { name: "Bob" };
const obj3 = { name: "Charlie" };

weakSet.add(obj1);
weakSet.add(obj2);
weakSet.add(obj3);
  1. 检查对象是否存在于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
  1. 从WeakSet中删除对象:
weakSet.delete(obj2);
console.log(weakSet.has(obj2));      // 输出: false

请注意,在没有其他引用指向对象时,即使该对象存在于WeakSet中,垃圾回收机制也会自动删除该对象。因此,无法获取WeakSet的大小也无法遍历其中的对象。WeakSet主要用于存储临时对象,例如在特定操作期间需要跟踪的对象。

4. WeakMap(弱引用映射)

  • WeakMap对象是键值对的集合,与Map不同的是,键必须是对象。
  • WeakMap中的键值对是无序的。
  • 使用弱引用的键意味着当没有其他引用指向键时,垃圾回收机制会自动删除WeakMap中的键值对。
  • WeakMap没有提供遍历的方法。

使用WeakMap(弱引用映射)时,你可以执行以下操作的示例代码:

  1. 创建一个空的WeakMap:
const weakMap = new WeakMap();
  1. 向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);
  1. 获取键对应的值:
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
  1. 检查键是否存在于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
  1. 从WeakMap中删除键值对:
weakMap.delete(obj2);
console.log(weakMap.has(obj2));     // 输出: false

请注意,与WeakSet一样,当没有其他引用指向键时,即使键存在于WeakMap中,垃圾回收机制也会自动删除该键及其对应的值。由于WeakMap的键必须是对象,因此无法获取WeakMap的大小,也无法遍历其中的键值对。WeakMap通常用于存储附加数据,而无需担心内存泄漏或手动清除数据。

需要注意的是,WeakSetWeakMap是弱引用结构,意味着在内存管理方面更加灵活,但也会带来一些限制。它们不能被迭代,也不能直接获取其大小。此外,WeakSet和WeakMap不是可枚举的,不能使用forEach()for...of循环来遍历其中的值或键值对。

附录:「简历必备」前后端实战项目(推荐:⭐️⭐️⭐️⭐️⭐️)

Vue.js 和 Egg.js 开发企业级健康管理项目
带你从入门到实战全面掌握 uni-app

你可能感兴趣的:(前端,学习,javascript)