JS中Map和Set数据结构
Set
1. 介绍
ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。Set
本身是一个构造函数,用来生成 Set 数据结构。
浏览器打印Set看一看,发现确实是一个构造函数,我们可以调用这个构造函数生成Set实例,同时,这个构造函数的prototype
上有很多属性和方法,我们的实例可以通过原型来访问这些属性和方法。
2. Set 实例的属性和方法
Set 结构的实例有以下属性。
Set.prototype.constructor
:构造函数,默认就是Set
函数。Set.prototype.size
:返回Set
实例的成员总数。
Set 实例的方法分为两大类:操作方法(用于操作数据)和遍历方法(用于遍历成员)。下面先介绍四个操作方法。
-
Set.prototype.add(value)
:添加某个值,返回 Set 结构本身。 -
Set.prototype.delete(value)
:删除某个值,返回一个布尔值,表示删除是否成功。 -
Set.prototype.has(value)
:返回一个布尔值,表示该值是否为Set
的成员。 -
Set.prototype.clear()
:清除所有成员,没有返回值。 -
Set.prototype.values()
:按照元素插入顺序返回一个具有Set
对象每个元素值的全新Iterator
对象。**values()**
方法按照元素插入顺序返回一个具有Set
对象每个元素值的全新Iterator
对象。keys()
方法是这个方法的别名(与Map
对象相似);他们的行为一致,都是返回Set
对象中的元素值。 -
Set.prototype.entries()
entries()
方法返回一个新的迭代器对象 ,这个对象的元素是类似[value, value]
形式的数组,value
是集合对象中的每个元素,迭代器对象元素的顺序即集合对象中元素插入的顺序。由于集合对象不像Map
对象那样拥有key
,然而,为了与Map
对象的API
形式保持一致,故使得每一个entry
的key
和value
都拥有相同的值,因而最终返回一个[value, value]
形式的数组。
上面这些属性和方法的实例如下。
s.add(1).add(2).add(2);
// 注意2被加入了两次
s.size // 2
s.has(1) // true
s.has(2) // true
s.has(3) // false
s.delete(2); // true
s.has(2) // false
s.clear() // undefined
const set1 = new Set();
set1.add(42);
set1.add('forty two');
const iterator1 = set1.values();
console.log(iterator1.next().value);
// expected output: 42
console.log(iterator1.next().value);
// expected output: "forty two"
var mySet = new Set();
mySet.add("foobar");
mySet.add(1);
mySet.add("baz");
var setIter = mySet.entries();
console.log(setIter.next().value); // ["foobar", "foobar"]
console.log(setIter.next().value); // [1, 1]
console.log(setIter.next().value); // ["baz", "baz"]
3. 基本使用
3.1 初始化一个set实例
// 直接通过Set构造函数new一个实例对象
const set = new Set()
// 通过数组(或者其它具有iterable接口的其他数据结构)作为参数,用来进行初始化
3.2 添加元素
可以通过add()
方法向 Set 结构加入成员,结果表明 Set 结构不会添加重复的值。
const set = new Set();
set.add(1);
set.add(2);
set.add(1);
// Set(2) {1, 2}
但是要注意:
向 Set 加入值的时候,不会发生类型转换,所以5
和"5"
是两个不同的值。Set 内部判断两个值是否不同,使用的算法叫做“Same-value-zero equality”,它类似于精确相等运算符(===
),主要的区别是向 Set 加入值时认为NaN
等于自身,而精确相等运算符认为NaN
不等于自身。
let set = new Set();
set.add(NaN);
set.add(NaN);
set // Set {NaN}
上面代码向 Set 实例添加了两次NaN
,但是只会加入一个。这表明,在 Set 内部,两个NaN
是相等的。
另外,两个对象总是不相等的。
let set = new Set();
set.add({});
set.size // 1
set.add({});
set.size // 2
// Set {NaN, NaN}
上面代码表示,由于两个空对象不相等,所以它们被视为两个值。