跳到主要内容

JavaScript Set 和 WeakSet

提示
  1. 独特元素集合:JavaScript的Set类似于数组,但不允许重复值,可存储不同类型的数据(如数字、字符串、对象等)。
  2. 操作和迭代元素:使用add()添加新元素,delete()clear()删除元素,以及has()检查元素存在。Set支持for...offorEach()方法进行迭代。
  3. WeakSet特性WeakSet仅能包含对象,并且不可迭代。它支持add()delete()has()方法,但与Set不同,WeakSet的元素只能是对象。

JavaScript ES6 引入了两种新的数据结构,即 SetWeakSet

Set类似于数组,允许我们存储多个项目,如数字、字符串、对象等。然而,与数组不同的是,Set不能包含重复的值。

创建JavaScript Set

要创建一个Set,需要使用new Set()构造器。例如,

// 创建Set
const set1 = new Set(); // 一个空的Set
console.log(set1); // Set {}

// 包含多种类型值的Set
const set2 = new Set([1, "hello", { count: true }]);
console.log(set2); // Set {1, "hello", {count: true}}

当重复值被传递给Set对象时,重复的值会被排除。

// 包含重复值的Set
const set3 = new Set([1, 1, 2, 2]);
console.log(set3); // Set {1, 2}

访问Set元素

可以使用values()方法访问Set元素,并使用has()方法检查Set中是否有某个元素。例如,

const set1 = new Set([1, 2, 3]);

// 访问Set的元素
console.log(set1.values()); // Set Iterator [1, 2, 3]

可以使用has()方法检查元素是否在Set中。例如,

const set1 = new Set([1, 2, 3]);

// 检查元素是否在Set中
console.log(set1.has(1));

添加新元素

可以使用add()方法向Set中添加元素。例如,

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

// 添加新元素
set.add(3);
console.log(set.values());

// 添加重复元素
// 不会被添加到Set
set.add(1);
console.log(set.values());

输出

Set Iterator [1, 2]
Set Iterator [1, 2, 3]
Set Iterator [1, 2, 3]

删除元素

可以使用clear()delete()方法从Set中删除元素。

delete()方法从Set中删除特定元素。例如,

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

// 删除特定元素
set.delete(2);
console.log(set.values()); // Set Iterator [1, 3]

clear()方法从Set中删除所有元素。例如,

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

// 删除Set的所有元素
set.clear();
console.log(set.values()); // Set Iterator []

遍历Sets

可以使用for...of循环或forEach()方法遍历Set元素。元素按插入顺序访问。例如,

const set = new Set([1, 2, 3]);

// 遍历Set
for (let i of set) {
console.log(i);
}

输出

1;
2;
3;

JavaScript WeakSet

WeakSet与Set类似。然而,WeakSet只能包含对象,而Set可以包含如字符串、数字、对象等任何数据类型。例如,

const weakSet = new WeakSet();
console.log(weakSet); // WeakSet {}

let obj = {
message: "Hi",
sendMessage: true,
};

// 将对象(元素)添加到WeakSet
weakSet.add(obj);

console.log(weakSet); // WeakSet {{message: "Hi", sendMessage: true}}

当尝试添加除对象以外的其他数据类型时,WeakSet会抛出错误。例如,

// 尝试将字符串添加到WeakSet
weakSet.add("hello");

// 抛出错误
// TypeError: Attempted to add a non-object key to a WeakSet
console.log(weakSet);

WeakSet方法

WeakSets拥有add()delete()has()方法。例如,

const weakSet = new WeakSet();
console.log(weakSet); // WeakSet {}

const obj = { a: 1 };

// 添加到weakSet
weakSet.add(obj);
console.log(weakSet); // WeakSet {{a: 1}}

// 检查元素是否在Set中
console.log(weakSet.has(obj)); // true

// 删除元素
weakSet.delete(obj);
console.log(weakSet); // WeakSet {}

WeakSets不可迭代

与Sets不同,WeakSets不可迭代。例如,

const weakSet = new WeakSet({ a: 1 });

// 遍历WeakSet
for (let i of weakSet) {
// TypeError
console.log(i);
}

数学集合操作

在JavaScript中,Set没有提供执行数学运算(如并集、交集、差集等)的内置方法。然而,我们可以编写程序来执行这些操作。

示例:Set并集操作

// 执行并集操作
// 包含两个集合的元素
function union(a, b) {
let unionSet = new Set(a);
for (let i of b) {
unionSet.add(i);
}
return unionSet;
}

// 两组水果的集合
let setA = new Set(["apple", "mango", "orange"]);
let setB = new Set(["grapes", "apple", "banana"]);

let result = union(setA, setB);

console.log(result);

输出

Set {"apple", "mango", "orange", "grapes", "banana"}

示例:Set交集操作

// 执行交集操作
// set a中也存在于set b中的元素
function intersection(setA, setB) {
let intersectionSet = new Set();

for (let i of setB) {
if (setA.has(i)) {
intersectionSet.add(i);
}
}
return intersectionSet;
}

// 两组水果的集合
let setA = new Set(["apple", "mango", "orange"]);
let setB = new Set(["grapes", "apple", "banana"]);

let result = intersection(setA, setB);

console.log(result);

输出

Set {"apple"}

示例:Set差集操作

// 执行差集操作
// set a中不存在于set b的元素
function difference(setA, setB) {
let differenceSet = new Set(setA);
for (let i of setB) {
differenceSet.delete(i);
}
return differenceSet;
}

// 两组水果的集合
let setA = new Set(["apple", "mango", "orange"]);
let setB = new Set(["grapes", "apple", "banana"]);

let result = difference(setA, setB);

console.log(result);

输出

Set {"mango", "orange"}

示例:Set子集操作

// 执行子集操作
// 如果set b的所有元素都在set a中,则为真
function subset(setA, setB) {
for (let i of setB) {
if (!setA.has(i)) {
return false;
}
}
return true;
}

// 两组水果的集合
let setA = new Set(["apple", "mango", "orange"]);
let setB = new Set(["apple", "orange"]);

let result = subset(setA, setB);

console.log(result);

输出

true;

JavaScript的SetsWeakSetsES6中引入。一些浏览器可能不支持它们的使用。要了解更多,请访问JavaScript Sets支持情况JavaScript WeakSets支持情况