一、Set是什么
—ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
—Set本身是一个构造函数,用来生成 Set 数据结构。
–返回对象
二、Set的定义
- Set函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。
const set = new Set([1, 2, 3, 4, 4]);
[...set]
// [1, 2, 3, 4]
// 例二
const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
items.size // 5
// 例三
const set = new Set(document.querySelectorAll('div'));
set.size // 56
// 类似于
const set = new Set();
document
.querySelectorAll('div')
.forEach(div => set.add(div));//add()方法向 Set 结构加入成员,结果表明
//Set 结构不会添加重复的值。
set.size // 56
- Set(参数)
----上面代码中,例一和例二都是Set函数接受数组作为参数,例三是接受类似数组的对象作为参数。
二、Set的参数
- 去除数组重复成员的方法。
// 去除数组的重复成员
[...new Set(array)]
[...new Set('ababbc')].join('')
// "abc"去除字符串里面的重复字符。
因为 Set 中的值总是唯一的,所以需要判断两个值是否相等。在ECMAScript规范的早期版本中,这不是基于和=操作符中使用的算法相同的算法。具体来说,对于 Set s, +0 (+0 严格相等于-0)和-0是不同的值。然而,在 ECMAScript 2015规范中这点已被更改。有关详细信息,请参阅浏览器兼容性 表中的“value equality for -0 and 0”。
另外,NaN和undefined都可以被存储在Set 中, NaN之间被视为相同的值(尽管 NaN ! NaN)。
let set = new Set();
let a = NaN;
let b = NaN;
set.add(a);
set.add(b);
set // Set {NaN}
- 上面代码向 Set 实例添加了两次NaN,但是只会加入一个。这表明,在 Set 内部,两个NaN是相等的。
- 另外,两个对象总是不相等的。
let set = new Set();
set.add({});
set.size // 1
set.add({});
set.size // 2
- 上面代码表示,由于两个空对象不相等,所以它们被视为两个值。
Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用;
Set 对象存储的值总是唯一的,所以需要判断两个值是否恒等。有几个特殊值需要特殊对待:
+0 与 -0 在存储判断唯一性的时候是恒等的,所以不重复;
undefined 与 undefined 是恒等的,所以不重复;
NaN 与 NaN 是不恒等的,但是在 Set 中只能存一个,不重复;
###三、Set的实例的属性和方法
####3.1、属性
- size
—Set.prototype.size
返回Set对象的值的个数。
####3.2、方法 - add(value);
----在Set对象尾部添加一个元素。返回该Set对象。 - clear()
----移除Set对象内的所有元素。 - delete(value)
—移除Set的中与这个值相等的元素,返回Set.prototype.has(value)在这个操作前会返回的值(即如果该元素存在,返回true,否则返回false)。Set.prototype.has(value)在此后会返回false。 - entries()
—返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值的[value, value]数组。为了使这个方法和Map对象保持相似, 每个值的键和值相等。 - forEach(callbackFn[, thisArg])
—按照插入顺序,为Set对象中的每一个值调用一次callBackFn。如果提供了thisArg参数,回调中的this会是这个参数。 - .has(value)
----返回一个布尔值,表示该值在Set中存在与否。 - keys()
—与values()方法相同,返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值。 - Set.prototype.values()
—返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值。
四、Set对象例子
let mySet = new Set();
mySet.add(1); // Set(1) {1}
mySet.add(5); // Set(2) {1, 5}
mySet.add(5); // Set { 1, 5 }
mySet.add("some text"); // Set(3) {1, 5, "some text"}
var o = {a: 1, b: 2};
mySet.add(o);
mySet.add({a: 1, b: 2}); // o 指向的是不同的对象,所以没问题
mySet.has(1); // true
mySet.has(3); // false
mySet.has(5); // true
mySet.has(Math.sqrt(25)); // true
mySet.has("Some Text".toLowerCase()); // true
mySet.has(o); // true
mySet.size; // 5
mySet.delete(5); // true, 从set中移除5
mySet.has(5); // false, 5已经被移除
mySet.size; // 4, 刚刚移除一个值
console.log(mySet); // Set {1, "some text", Object {a: 1, b: 2}, Object {a: 1, b: 2}}
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Set
- 迭代Set
// 迭代整个set
// 按顺序输出:1, "some text"
for (let item of mySet) console.log(item);
// 按顺序输出:1, "some text"
for (let item of mySet.keys()) console.log(item);
// 按顺序输出:1, "some text"
for (let item of mySet.values()) console.log(item);
// 按顺序输出:1, "some text"
//(键与值相等)
for (let [key, value] of mySet.entries()) console.log(key);
// 转换Set为Array
var myArr = Array.from(mySet); // [1, "some text"]
// 如果在HTML文档中工作,也可以:
mySet.add(document.body);
mySet.has(document.querySelector("body")); // true
// Set 和 Array互换
mySet2 = new Set([1,2,3,4]);
mySet2.size; // 4
[...mySet2]; // [1,2,3,4]
// intersect can be simulated via
var intersection = new Set([...set1].filter(x => set2.has(x)));
// difference can be simulated via
var difference = new Set([...set1].filter(x => !set2.has(x)));
// 用forEach迭代
mySet.forEach(function(value) {
console.log(value);
});
// 1
// 2
// 3
// 4