检验浏览器支持情况
'use strict'
var map = new Map();
var set = new Set();
alert('浏览器支持map和set')
能alert出来就说明支持
概念
Set——新的数据结构,它类似于数组,但成员的值都是唯一的,没有重复的值。Set本身是一个构造函数,用来生成Set数据结构
通过add向set结构中添加成员,可知set结构不会添加重复的值.(这里add是set结构的方法)
var s = new Set();
[2,3,5,2,6,3,5].map(x => s.add(x));
for(i of s){console.log(i);} // 2 3 5 6
Set函数接受一个数组或类数组对象作为参数,用于初始化
var set = new Set([1,2,3]);
console.log([...set]); // [1, 2, 3]
console.log(set.size); // 3
console.log(set); // Set(3) {1, 2, 3}
向Set加入值时不会发生类型的转换。set内部判断两个值是否相等的算法类似于 === ,也就是说两个对象总是不相等的,唯一的例外是NaN等于自身
var set = new Set();
set.add({});
console.log(set.size); // 1
set.add({});
console.log(set.size); // 2(这里两个对象可以重复添加,说明两个对象是不相等的)
var a = new Set();
a.add(1);
console.log(a.size); // 1
a.add(1);
console.log(a.size); // 1(这里两个1不能重读添加,说明1===1,而且set不可以添加重复的数据)
a.add(2);
console.log(a.size); // 2
二:Set实例的属性
Set.prototype.constructor
: 构造函数,默认就是Set函数
Set.prototype.size
: 返回Set实例的成员总数
三:Set实例的方法
add(value)——添加值,返回Set本身
delete(value)——删除值,返回布尔值
has(vaalue)——是否有值,返回布尔值
clear()——清除所有成员,没有返回值
var set = new Set();
set.add(1);
console.log(set.size); // 1
console.log([...set]); // [1]
console.log(set); // Set(1) {1}
set.add(2).add(2);
console.log(set.size); // 2,其中2没有被重复添加进去
console.log(set.has(2)); // true
console.log(set.has(3)); // false
console.log(set.delete(1)); // true
console.log(set.has(1)); // false
四:小例子
Array.from()可以将set结构转化为数组
var items = new Set([1,2,4]);
console.log(items); // Set(3) {1, 2, 4}
var array = Array.from(items)
console.log(array); // [1,2,4]
用途:数组去重
var items = new Set([1,2,4,3,2,1]);
console.log(items); // Set(3) {1, 2, 4, 3}
var array = Array.from(items)
console.log(array); // [1,2,4,3]
function dedupe(array){
return Array.from(new Set(array))
}
console.log(dedupe([1,4,2,4,1,3,5])); // [1, 4, 2, 3, 5]
五:遍历操作
四种遍历方法,用于遍历Set结构成员
1. keys(): 键的遍历
2. values(): 值的遍历
3. entries(): 键值对的遍历
4. forEach(): 使用回调函数遍历每个成员
前三者返回的都是遍历器对象,而key和value是一个值,所以前两者返回的值一模一样
let set = new Set([1,2,4,6,3]);
console.log(set.keys()); // SetIterator {1, 2, 4, 6, 3}
for(let items of set.keys()){
console.log(items); // 1 2 4 6 3
}
console.log(set.values()); // SetIterator {1, 2, 4, 6, 3}
console.log(set.entries()); // SetIterator {[1, 1], [2, 2], [4, 4], [6, 6], [3, 3]}
// 这里entries返回的是键值对的数组,其中键值完全相同
Set结构的实例默认是可遍历的,默认遍历器生成函数就是它的values方法
可以省略values方法,直接遍历用for of 方法循环遍历set(两者得到了相同的遍历结果)
let set = new Set([1,2,4,6,3]);
for(x of set){
console.log(x); // 1 2 4 6 3
}
扩展运算符内部使用for of 循环,所以也可以用于set结构
let set = new Set([2,5,12,3,2,3]);
let arr = [...set]
console.log(arr); // [2, 5, 12, 3],同时去重了
数组的map和filter方法也可以用于Set方法(p154)
WeakSet——也是不重复值的集合
WeakSet与Set的区别
1. WeakSet的成员只能是对象,而不能是其他类型的值
2. WeakSet中的对象都是弱引用。即垃圾回收机制不考虑WeakSet对该对象的引用。也就是说:如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于weakset中。这一特点意味着:无法引用WeakSet的成员。因此,WeakSet是不可遍历的。
var ws = new WeakSet(); // WeakSet是构造函数,可以用new命令创建WeakSet数据结构
ws.add(1); // error
ws.add(Symbol()); // error
var obj = {};
ws.add(obj); // 可以
上述例子说明:WeakSet只能添加对象类型的成员
WeakSet可以接受数组或者类数组对象作为参数
(实际上具备iterable接口的对象都可以作为WeakSet的参数),该数组的所有成员都会自动成为WeakSet实例对象的成员
var a = [[1,2],[3,4]];
var ws = new WeakSet(a);
console.log(ws); // WeakSet {[3, 4], [1, 2]}
console.log(ws.size); // undefined,因为没有size属性,没有办法遍历成员
这里:没有size属性,不能遍历,因为成员都是弱引用,随时可能消失,遍历机制无法保证成员存在,很可能刚刚结束遍历,成员就取不到了。
WeakSet的一个用处:存储DOM节点,而不用担心这些节点从文档中移除时引起内存泄露
三个方法
1. WeakSet.prototype.add(value)
2. WeakSet.prototype.delete(value)
3. WeakSet.prototype.has(value)