跳到主要内容

Set

一、认识


SetES6 新增的一种集合类型。允许你存储任何类型的唯一值,无论是原始值或者是对象引用。即Set 中的元素是唯一的。

二、语法


2.1 new Set()

通过new Set()创建空集合

const set = new Set();
console.log(set); // Set(0) {size: 0}

2.2 new Set([])

通过new Set([])创建集合的同时初始化元素,并且自动去除重复的元素

const set = new Set([1,2,3,4,1,1]);
console.log(set); // Set(4) {1, 2, 3, 4}

三、属性


3.1 set.size

set.size 返回Set对象中的值的个数

语法

const set = new Set();
set.add(1);
set.add(2);
console.log(set); // Set(2) {1, 2}
console.log(set.size); // 2

四、方法


4.1 set.add()

set.add()Set对象尾部添加一个元素,返回该Set对象。因此**Set实例.add()**可以链式调用。

语法

单个使用
const set = new Set();
set.add(1);
set.add(2);
console.log(set); // Set(2) {1, 2}
链式调用
const set = new Set();
set.add(1).add(2);
console.log(set); // Set(2) {1, 2}

4.2 set.has()

set.has() 返回一个布尔值,表示该值在Set中存在与否。

语法

const set = new Set();
set.add(1);
set.add(2);
console.log(set); // Set(2) {1, 2}
console.log(set.has(1)); // true

4.3 set.delete()

set.delete() 移除Set中与这个值相等的元素,返回**Set.prototype.has(value)**在这个操作前会返回的值(即如果该元素存在,返回true,否则返回false)。Set.prototype.has(value)在此后会返回false

语法

const set = new Set();
set.add(1);
set.add(2);
console.log(set); // Set(2) {1, 2}
set.delete(1);
console.log(set); // Set(1) {2}

4.4 set.clear()

set.clear() 移除Set对象内的所有元素。

语法

const set = new Set();
set.add(1);
set.add(2);
console.log(set); // Set(2) {1, 2}
set.clear();
console.log(set); // Set(0) {size: 0}

4.5 set.keys()

set.keys() 返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值。

语法

const set = new Set([1,2,3,4,5,8]);
for(let key of set.keys()){
console.log(key); // 1 2 3 4 5 8
}

4.6 set.values()

set.values() 返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值。

语法

const set = new Set([1,2,3,4,5,8]);
for(let value of set.values()){
console.log(value); // 1 2 3 4 5 8
}

4.7 set.entries()

set.entries() 返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值的[value, value]数组。为了使这个方法和Map对象保持相似, 每个值的键和值相等。

语法

const set = new Set([1,2,3,4,5,8]);
for(let value of set.entries()){
console.log(value); // [1, 1] [2, 2]  [3, 3] [4, 4]  [5, 5] [8, 8]
}

4.9 set.forEach()

set.forEach() 按照插入顺序,为Set对象中的每一个值调用一次callBackFn。如果提供了thisArg参数,回调中的this会是这个参数。

语法

const set = new Set([1,2,3,4,5,8]);
set.forEach((value,key)=>{
console.log(value,key); // 1 1 2 2 3 3 4 4 5 5 8 8
});

五、转换数组


5.1 …… 转换

const set = new Set([1,2,3,4,5,8]);
console.log([...set]); // [1, 2, 3, 4, 5, 8]

5.2 Array.from

const set = new Set([1,2,3,4,5,8]);
console.log(Array.from(set)); // [1, 2, 3, 4, 5, 8]

六、相等算法


Set中的值总是唯一的,所以需要判断两个值是否相等。Set的比较基于sameValueZero算法:

sameValueZero算法
function sameValueZero(x, y) {
return (
x === y ||
(typeof x === "number" &&
typeof y === "number" &&
isNaN(x) &&
isNaN(y))
);
}

对于NaN而言,Set会直接认为NaN 是与 NaN 相等的(虽然 NaN !== NaN)

const set = new Set();
set.add(NaN).add(NaN);
console.log(set); // Set(1) {NaN}
console.log(NaN===NaN); // NaN

剩下所有其它的值是根据 === 运算符的结果判断是否相等

const set = new Set();
set.add(null).add(undefined);
console.log(set); // Set(2) {null, undefined}
console.log(null===undefined); // false

在目前的ECMAScript规范中,-0+0 被认为是相等的