Set和Map

Set

Set可以看作是一组key的集合,但不存储value.由于key是不重复的,所以在Set中,没有重复的key。
Set本身就是一个构造函数,所以可使用new来创建Set数据。要创建一个Set,需要提供一个Array作为输入,或直接创建一个空Set.

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

Set中不会含有重复的成员,也不会进行类型转化。

var set = new Set([1, 2, 2, 3, '3']);
set;    //  Set(4) {1, 2, 3, "3"}

Set的属性和方法

add(val): 添加某个值,返回Set结构本身。
delete(val): 删除某个值,返回一个布尔值,表示删除是否成功。
has(val): 返回一个布尔值,表示该值是否为Set的成员。
clear(val): 返回一个布尔值,表示该值是否为Set的成员。
size: 返回Set实例的成员总数。

var s = new Set();
s.add(1).add(2).add(2);
console.log(s);   //  Set(2) {1, 2}

s.size;         //  2
s.has(1);       //  true
s.has(2);       //  true
s.has(3);       //  false

s.delete(1);    
s.has(1);       //  false

console.log(s); //  Set(1) {2}
s.clear();
console.log(s); //  Set(0) {}

注意:上面的代码有两次add(2),结果输出的Set中只有一个2,这是因为Set中没有重复的成员。
keys(): 返回键名的遍历器
values(): 返回键值的遍历器
entries(): 返回键值对的遍历器
forEach(): 使用回调函数遍历每个成员
需要特别注意的是,Set的遍历顺序就是插入顺序。
由于Set没有键值或者说没有键名,所以keys()和values()方法返回的结果完全一致。

let set = new Set(['red', 'green', 'blue']);

for (let item of set.keys()) {
  console.log(item);
}
// red
// green
// blue
for (let item of set.values()) {
  console.log(item);
}
// red
// green
// blue
for (let item of set.entries()) {
  console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]
let set = new Set([1, 2, 3]);
set.forEach((value, key) => console.log(value * 2) )
// 2
// 4
// 6

扩展运算符(...)内部使用for...of循环,所以也可以用于 Set 结构。

let set = new Set(['red', 'green', 'blue']);
let arr = [...set];
//  ['red', 'green', 'blue']

WeakSet

与Set一样,WeakSet是一个构造函数,可以使用new命令创建WeakSet数据结构。

const ws = new WeakSet();

WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。

let set = new WeakSet(),
    key = {};
// 将对象加入 set
set.add(key);
console.log(set.has(key));      // true
// 移除对于键的最后一个强引用,同时从 Weak Set 中移除
key = null;
console.log(set.has(key));      // false

WeakSet必须接受一个对象作为参数,不接受基本类型的数据作为参数

var set = new Set([1,2]);
set;            //  Set(2) {1, 2}
var weakSet1 = new WeakSet([1,2]);  //  TypeError: Invalid value used in weak set
var weakSet2 = new WeakSet([[1],[2]]);
weakSet2;       //  WeakSet {Array(1), Array(1)}

WeakSet结构也有add(value), delete(value), has(value)方法。

Map

JavaScript的对象有个小问题,就是键必须是字符串。但实际上Number或者其他数据类型作为键也是非常合理的。为了解决这个问题,最新的ES6规范引入了新的数据类型Map。
Map是一组键值对的结构,具有极快的查找速度。
举个例子,假设要根据同学的名字查找对应的成绩,如果用Array实现,需要两个Array:

var names = ['Michael', 'Bob', 'Tracy'];
var scores = [95, 75, 85];

如果用Map实现,只需要一个“名字”-“成绩”的对照表,直接根据名字查找成绩。

var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael'); // 95

Map结构的属性和方法

** size, set(key, value), get(key), has(key), delete(key), clear() **

const map = new Map();
map.set('foo', true);
map.set('bar', false);

map.size // 2
const m = new Map();

const hello = function() {console.log('hello');};
m.set(hello, 'Hello ES6!') // 键是函数

m.get(hello)  // Hello ES6!

遍历方法

  • keys():返回键名的遍历器。
  • values():返回键值的遍历器。
  • entries():返回所有成员的遍历器。
  • forEach():遍历 Map 的所有成员。

Map 的遍历顺序就是插入顺序。

const map = new Map([
  ['F', 'no'],
  ['T',  'yes'],
]);
for (let key of map.keys()) {
  console.log(key);
}
// "F"
// "T"
for (let value of map.values()) {
  console.log(value);
}
// "no"
// "yes"
for (let item of map.entries()) {
  console.log(item[0], item[1]);
}
// "F" "no"
// "T" "yes"

// 或者
for (let [key, value] of map.entries()) {
  console.log(key, value);
}
// "F" "no"
// "T" "yes"

// 等同于使用map.entries()
for (let [key, value] of map) {
  console.log(key, value);
}
// "F" "no"
// "T" "yes"

Map 结构的默认遍历器接口(Symbol.iterator属性),就是entries方法。

Map转化为数组

Map 转为数组最方便的方法,就是使用扩展运算符(...)

const myMap = new Map()
  .set(true, 7)
  .set({foo: 3}, ['abc']);
[...myMap]
// [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
原文地址:https://www.cnblogs.com/renzhiwei2017/p/7351207.html