当谈到JavaScript中的数据结构时,Set和Map是两个非常有用且强大的类型。它们提供了一种有效地存储和操作数据的方式,比传统的数组和对象更灵活。
Set
Set是一种集合数据结构,其中每个值都必须是唯一的。它不允许重复的元素存在。创建一个Set很简单:
javascript
const mySet = new Set();
Set的常用方法:
-
add(value): 向Set中添加一个值。如果该值已存在,则不会重复添加。
javascriptconst mySet = new Set(); mySet.add(1); mySet.add(2);
-
delete(value): 删除Set中指定的值。
javascriptmySet.delete(1);
-
has(value): 检查Set中是否存在指定的值,返回布尔值。
javascriptconsole.log(mySet.has(2)); // true console.log(mySet.has(3)); // false
-
clear(): 清空Set中的所有值。
javascriptmySet.clear();
-
size: 获取Set中值的数量。
javascriptconsole.log(mySet.size); // 0
-
forEach(callbackFn, thisArg): 遍历Set中的每个值,可以传入回调函数和可选的上下文。
javascriptmySet.forEach((value) => { console.log(value); });
Set的应用场景
1.储存唯一数据: Set 保证其中的值是唯一的,使其在去重数组等场景中非常高效。 2.高效的查找: 使用 Set 的 has
方法可以高效地检查一个值是否存在于集合中。 3.集合运算: Set 提供了一些集合运算的方法,如并集、交集、差集等,方便进行集合操作。
javascript
const set1 = new Set([1, 2, 3]);
const set2 = new Set([2, 3, 4]);
const union = new Set([...set1, ...set2]); // 并集
const intersection = new Set([...set1].filter(value => set2.has(value))); // 交集
const difference = new Set([...set1].filter(value => !set2.has(value))); // 差集
console.log([...union]); // [1, 2, 3, 4]
console.log([...intersection]); // [2, 3]
console.log([...difference]); // [1]
WeakSet
WeakSet
是一种集合数据结构,它只能包含对象,并且这些对象是弱引用的。弱引用意味着如果没有其他引用指向对象,对象会被垃圾回收器回收,即使它存在于WeakSet
中。
创建和基本操作
javascript
const weakSet = new WeakSet();
const obj1 = {};
const obj2 = {};
weakSet.add(obj1);
weakSet.add(obj2);
console.log(weakSet.has(obj1)); // true
weakSet.delete(obj2);
console.log(weakSet.has(obj2)); // false
与Set
不同,WeakSet
没有size
属性,也没有forEach
方法,因为这可能导致无法预测的行为。
使用场景
对象的临时关联: WeakSet
通常用于存储对象的临时关联,这样当对象被销毁时,它们也会被自动从集合中移除,有助于避免内存泄漏。
Map
Map是一种键值对的集合,其中键和值可以是任意类型的数据。与对象不同,Map保留了元素的插入顺序。
javascript
const myMap = new Map();
Map的常用方法:
-
set(key, value): 向Map中添加键值对。
javascriptconst myMap = new Map(); myMap.set('name', 'John'); myMap.set('age', 25);
-
get(key): 获取Map中指定键对应的值。
javascriptconsole.log(myMap.get('name')); // John
-
delete(key): 删除Map中指定键值对。
javascriptmyMap.delete('age');
-
has(key): 检查Map中是否存在指定的键,返回布尔值。
javascriptconsole.log(myMap.has('age')); // false
-
clear(): 清空Map中的所有键值对。
javascriptmyMap.clear();
-
size: 获取Map中键值对的数量。
javascriptconsole.log(myMap.size); // 0
-
keys(): 返回一个包含Map中所有键的迭代器。
javascriptconst keysIterator = myMap.keys(); for (const key of keysIterator) { console.log(key); }
-
values(): 返回一个包含Map中所有值的迭代器。
javascriptconst valuesIterator = myMap.values(); for (const value of valuesIterator) { console.log(value); }
-
entries(): 返回一个包含Map中所有键值对的迭代器。
javascriptconst entriesIterator = myMap.entries(); for (const [key, value] of entriesIterator) { console.log(`${key}: ${value}`); }
Map的应用场景
-
键值对存储: Map 是一种键值对的集合,非常适合存储和查找键值对信息。
javascriptconst userInfo = new Map(); userInfo.set('name', 'John'); userInfo.set('age', 25); console.log(userInfo.get('name')); // John
-
对象作为键: Map 允许使用对象作为键,这在需要以对象为唯一标识的场景中非常有用。
javascriptconst objKey1 = { id: 1 }; const objKey2 = { id: 2 }; const objectMap = new Map(); objectMap.set(objKey1, 'Value 1'); objectMap.set(objKey2, 'Value 2'); console.log(objectMap.get(objKey1)); // Value 1
-
迭代和遍历: Map 提供了多种迭代方法,如
keys
、values
、entries
,可以方便地遍历键、值或键值对。javascriptconst myMap = new Map([ ['name', 'John'], ['age', 25], ['gender', 'Male'] ]); for (const key of myMap.keys()) { console.log(key); } // Output: // name // age // gender
-
保持键值顺序: 与对象不同,Map 保持键值对的揺入顺序,这在需要有序存储的情况下非常有用。
javascriptconst orderedMap = new Map([ ['b', 2], ['a', 1], ['c', 3] ]); console.log([...orderedMap.keys()]); // ['b', 'a', 'c']
WeakMap
WeakMap
是一种键值对的集合,其中键是对象,而值可以是任意类型。与Map
不同,WeakMap
中的键也是弱引用的。
创建和基本操作
javascript
const weakMap = new WeakMap();
const key1 = {};
const key2 = {};
const value1 = 'Hello';
const value2 = 'World';
weakMap.set(key1, value1);
weakMap.set(key2, value2);
console.log(weakMap.get(key1)); // Hello
weakMap.delete(key2);
console.log(weakMap.has(key2)); // false
与WeakSet
一样,WeakMap
也没有size
属性和forEach
方法。
使用场景
-
对象的临时关联:
WeakMap
通常用于存储对象的临时关联,这样当对象被销毁时,它们也会被自动从集合中移除,有助于避免内存泄漏。 -
私有数据存储:
WeakMap
可以用于存储对象的私有数据,因为在对象被销毁时,与之关联的数据也会被清除。 -
缓存机制: 可以利用
WeakMap
来实现简单的缓存机制,当某个键不再被引用时,对应的值也会被垃圾回收。
总结
总体而言,Set
Map
提供了更丰富的数据结构和操作方法,可以根据具体需求选择更合适的数据类型;WeakSet
和WeakMap
提供了对对象的弱引用,使得它们在需要确保对象生命周期与集合一致、以及避免内存泄漏的场景中非常有用。它们在 JavaScript 中的应用广泛,分别适用于处理唯一值集合和键值对集合的场景,有助于提高代码的可读性和性能。
最后的最后,我们来写一道leetcode题来巩固一下今天的知识吧!!!