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; // 2s.has(1); // trues.has(2); // trues.has(3); // falses.delete(1); s.has(1); // falseconsole.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// bluefor (let item of set.values()) { console.log(item);}// red// green// bluefor (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 = {};// 将对象加入 setset.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 setvar 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' ] ] ]