JavaScript 中的Set從基礎(chǔ)到高級用法
前言
在前端開發(fā)中,我們經(jīng)常需要處理去重、集合運算、唯一性校驗等需求。過去我們通常使用 Array 配合 filter + indexOf 或 reduce 來實現(xiàn),但代碼冗長且性能不佳。
為了解決這類問題,ES6 引入了 Set 數(shù)據(jù)結(jié)構(gòu)。
本文將帶你全面掌握 Set 的 定義、特性、API、使用場景、性能對比與最佳實踐,助你在項目中高效處理“唯一性”問題。
一、什么是 Set?
定義
Set是一個 唯一值的集合,它允許存儲任何類型的值,且每個值在集合中只出現(xiàn)一次。
const set = new Set();
核心特性
| 特性 | 說明 |
|---|---|
| 自動去重 | 重復(fù)添加的值會被忽略 |
| 大小可查 | set.size 直接獲取元素數(shù)量 |
| 有序存儲 | 按插入順序遍歷 |
| 無原型污染 | 不繼承 Object.prototype,更“干凈” |
| 性能更優(yōu) | 查找、插入、刪除操作平均時間復(fù)雜度為 O(1) |
二、Set 的基本用法
1. 創(chuàng)建 Set
// 空 Set
const set = new Set();
// 從數(shù)組初始化(自動去重)
const set = new Set([1, 2, 3, 2, 1]); // Set { 1, 2, 3 }
// 從字符串創(chuàng)建(字符去重)
const charSet = new Set('hello'); // Set { 'h', 'e', 'l', 'o' }2. 增刪查 API
| 方法 | 說明 | 返回值 |
|---|---|---|
add(value) | 添加值 | Set 本身(可鏈?zhǔn)秸{(diào)用) |
has(value) | 判斷值是否存在 | boolean |
delete(value) | 刪除值 | boolean(是否刪除成功) |
clear() | 清空所有 | void |
const userSet = new Set();
userSet.add('Alice');
userSet.add('Bob');
userSet.add('Alice'); // 重復(fù),忽略
console.log(userSet.has('Alice')); // true
console.log(userSet.delete('Bob')); // true
console.log(userSet.size); // 1
userSet.clear();
console.log(userSet.size); // 03. 鏈?zhǔn)秸{(diào)用
new Set() .add(1) .add(2) .add(3);
三、Set 的遍歷方式
Set 提供了三種遍歷方法,返回 迭代器(Iterator):
| 方法 | 返回值 | 說明 |
|---|---|---|
keys() | 值的迭代器 | 與 values() 相同(兼容 Map) |
values() | 值的迭代器 | 默認(rèn)遍歷方式 |
entries() | 鍵值對的迭代器 | 每個元素是 [value, value] |
1.for...of遍歷
const set = new Set(['a', 'b', 'c']);
// 遍歷值
for (const value of set) {
console.log(value);
}
// a
// b
// c
// 或使用 values()
for (const value of set.values()) {
console.log(value);
}
// 遍歷鍵值對(每個鍵值相同)
for (const [key, value] of set.entries()) {
console.log(key, value); // a a, b b, c c
}2.forEach遍歷
set.forEach((value, key) => {
console.log(value); // 注意:key === value
});
注意:
forEach的參數(shù)中key和value相同,這是為了與Map保持一致。
四、Set 與 Array 的對比
| 特性 | Set | Array |
|---|---|---|
| 唯一性 | 自動去重 | 允許重復(fù) |
| 大小 | set.size | arr.length |
| 順序 | 插入順序 | 插入順序 |
| 查找性能 | O(1) | O(n) |
| 序列化 | 需手動處理 | JSON.stringify() 支持 |
| 語法 | set.has(value) | arr.includes(value) |
何時使用 Set?
| 場景 | 推薦 |
|---|---|
| 去重 | Set(最優(yōu)雅) |
| 頻繁查找是否存在 | Set(性能優(yōu)) |
| 需要保持唯一性 | Set |
需要索引訪問(arr[0]) | Array |
需要 map、filter 等方法 | Array(需轉(zhuǎn)換) |
| 數(shù)據(jù)量小、操作簡單 | 可任選 |
五、Set 的高級用法
1. 數(shù)組去重(最簡潔寫法)
const arr = [1, 2, 2, 3, 3, 4]; const uniqueArr = [...new Set(arr)]; // [1, 2, 3, 4] // 或 const uniqueArr = Array.from(new Set(arr));
2. 集合運算(交集、并集、差集)
const a = new Set([1, 2, 3]);
const b = new Set([2, 3, 4]);
// 并集
const union = new Set([...a, ...b]); // {1, 2, 3, 4}
// 交集
const intersection = new Set([...a].filter(x => b.has(x))); // {2, 3}
// 差集(a - b)
const difference = new Set([...a].filter(x => !b.has(x))); // {1}3. 數(shù)組元素唯一性校驗
const hasDuplicates = (arr) => {
return new Set(arr).size !== arr.length;
};
hasDuplicates([1, 2, 2]); // true
hasDuplicates([1, 2, 3]); // false4. 轉(zhuǎn)換為 Array / Object
const set = new Set(['a', 'b', 'c']); // Set → Array const arr = [...set]; // ['a', 'b', 'c'] // 或 Array.from(set) // Array → Set const newSet = new Set(arr);
六、WeakSet:更輕量的 Set
什么是 WeakSet?
- 值必須是 對象
- 值是 弱引用,不會阻止垃圾回收
- 不能遍歷,沒有
size、clear()等 - 用于對象標(biāo)記、私有數(shù)據(jù)、緩存
const ws = new WeakSet();
const obj = { name: 'Alice' };
ws.add(obj);
console.log(ws.has(obj)); // true
// 當(dāng) obj 被銷毀,WeakSet 中的引用也會被自動清除與 Set 對比
| 特性 | Set | WeakSet |
|---|---|---|
| 值類型 | 任意 | 對象 |
| 弱引用 | 不支持 | 支持 |
| 可遍歷 | 支持 | 不支持 |
size / clear() | 支持 | 不支持 |
| 用途 | 通用唯一集合 | 對象標(biāo)記、緩存、私有數(shù)據(jù) |
七、常見問題
1.Set和Array去重的區(qū)別?
答:
Set去重基于SameValueZero算法,NaN === NaN。Array的indexOf使用===,NaN !== NaN,無法去重NaN。Set性能更好,代碼更簡潔。
2.Set如何判斷重復(fù)?
答:使用
SameValueZero比較算法:
===大部分情況- 特殊:
NaN被認(rèn)為相等
const set = new Set([NaN, NaN]); console.log(set.size); // 1
3.WeakSet有什么用?
答:用于對象的臨時標(biāo)記、私有數(shù)據(jù)存儲、避免內(nèi)存泄漏。例如:
const disabledElements = new WeakSet(); disabledElements.add(button); // 當(dāng) button 被移除,標(biāo)記自動消失
4. 如何實現(xiàn)對象內(nèi)容去重?
答:需手動實現(xiàn),如將對象序列化為字符串:
const objSet = new Set();
const key = JSON.stringify({ id: 1 });
objSet.add(key);
注意順序、類型、
undefined處理。
總結(jié)
| 要點 | 說明 |
|---|---|
| 核心優(yōu)勢 | 自動去重、查找快(O(1))、有序、可查大小 |
| 適用場景 | 數(shù)組去重、集合運算、唯一性校驗、緩存鍵 |
| 遍歷方式 | for...of、forEach、values/entries |
| 轉(zhuǎn)換方法 | [...set]、Array.from(set) |
| 內(nèi)存優(yōu)化 | WeakSet 用于對象的弱引用場景 |
到此這篇關(guān)于JavaScript 深入理解Set:從基礎(chǔ)到高級用法的文章就介紹到這了,更多相關(guān)js set用法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript計算器網(wǎng)頁版實現(xiàn)代碼分享
這篇文章主要為大家詳細(xì)介紹了JavaScript計算器網(wǎng)頁版實現(xiàn)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-07-07

