类似于数组,但是成员的值都是唯一的,没有重复的值。
var arr = [1,1,2,3]
[...new Set(arr)] // [1, 2, 3]
Array.from(new Set(arr)) // [1, 2, 3]
[...new Set('ababbc')].join('') // abc
属性:
- Set.prototype.constructor:构造函数,默认就是Set函数。
- Set.prototype.size:返回Set实例的成员总数。
方法:
- Set.prototype.add(value):添加某个值,返回 Set 结构本身。
- Set.prototype.delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
- Set.prototype.has(value):返回一个布尔值,表示该值是否为Set的成员。
- Set.prototype.clear():清除所有成员,没有返回值。
- Set.prototype.keys():返回键名的遍历器
- Set.prototype.values():返回键值的遍历器
- Set.prototype.entries():返回键值对的遍历器
- Set.prototype.forEach():使用回调函数遍历每个成员
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}
// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// set {2, 3}
// 差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1}
WeakSet 结构与 Set 类似
- 成员只能是对象
- 没有size属性,不可遍历
- 不计入垃圾回收机制
方法:
- WeakSet.prototype.add(value):向 WeakSet 实例添加一个新成员。
- WeakSet.prototype.delete(value):清除 WeakSet 实例的指定成员。
- WeakSet.prototype.has(value):返回一个布尔值,表示某个值是否在 WeakSet 实例之中。
// 是a数组的成员成为 WeakSet 的成员,而不是a数组本身
const a = [[1, 2], [3, 4]];
const ws = new WeakSet(a);
// WeakSet {[1, 2], [3, 4]}
它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键
- +0 == -0
- NaN == NaN
const map = new Map([
['foo', 1],
['bar', 2]
])
new Map(new Set([
['foo', 1],
['bar', 2]
]))
let map = new Map();
map.set(-0, 123);
map.get(+0) // 123
map.set(true, 1);
map.set('true', 2);
map.get(true) // 1
map.set(undefined, 3);
map.set(null, 4);
map.get(undefined) // 3
map.set(NaN, 123);
map.get(NaN) // 123
属性:
- size
方法:
- Map.prototype.set(key, value)
- Map.prototype.get(key)
- Map.prototype.has(key)
- Map.prototype.delete(key)
- Map.prototype.clear()
- Map.prototype.keys():返回键名的遍历器。
- Map.prototype.values():返回键值的遍历器。
- Map.prototype.entries():返回所有成员的遍历器。
- Map.prototype.forEach():遍历 Map 的所有成员。
- Map转为数组
- 扩展运算符
- Array.from
var map = new Map([['a', 1], ['b', 2]])
// 扩展运算符
[...map]
// Array.from
Array.from(map)
- 数组转Map
- Map构造函数
var map = new Map([['a', 1], ['b', 2]])
- Map转为对象
- 遍历
function strMapToObj(strMap) {
let obj = Object.create(null);
for (let [k,v] of strMap) {
obj[k] = v;
}
return obj;
}
var map = new Map([['a', 1], ['b', 2]])
strMapToObj(map)
- 对象转为 Map
- 遍历
function objToStrMap(obj) {
let strMap = new Map();
for (let k of Object.keys(obj)) {
strMap.set(k, obj[k]);
}
return strMap;
}
objToStrMap({a: 1, b: 2})
- Map转为JSON
- Map 的键名都是字符串:转为对象 JSON
- Map 的键名有非字符串:转为数组 JSON
function strMapToObj(strMap) {
let obj = Object.create(null);
for (let [k,v] of strMap) {
obj[k] = v;
}
return obj;
}
function strMapToJson(strMap) {
return JSON.stringify(strMapToObj(strMap));
}
var map = new Map([['a', 1], ['b', 2]])
strMapToJson(myMap)
// '{"a":1,"b":2}'
function mapToArrayJson(map) {
return JSON.stringify([...map]);
}
mapToArrayJson(myMap)
// '[["a",1],["b",2]]'
- JSON 转为 Map
- 键名都是字符串
- 整个 JSON 就是一个数组,且每个数组成员本身,又是一个有两个成员的数组
function objToStrMap(obj) {
let strMap = new Map();
for (let k of Object.keys(obj)) {
strMap.set(k, obj[k]);
}
return strMap;
}
function jsonToStrMap(jsonStr) {
return objToStrMap(JSON.parse(jsonStr));
}
jsonToStrMap('{"a": 1, "b": 2}')
// Map {'a' => 1, 'b' => 2}
function jsonToMap(jsonStr) {
return new Map(JSON.parse(jsonStr));
}
jsonToMap('[["a",1],["b",2]]')
// Map {'a' => 1, 'b' => 2}
WeakMap结构与Map结构类似
- 只接受对象作为键名
- 不计入垃圾回收机制
WeakMap 弱引用的只是键名,而不是键值。键值依然是正常引用。
const wm = new WeakMap();
let key = {};
let obj = {foo: 1};
wm.set(key, obj);
obj = null;
wm.get(key)
// Object {foo: 1}
上面代码中,键值obj是正常引用。所以,即使在 WeakMap 外部消除了obj的引用,WeakMap 内部的引用依然存在。
let myElement = document.getElementById('logo');
let myWeakmap = new WeakMap();
myWeakmap.set(myElement, {timesClicked: 0});
myElement.addEventListener('click', function() {
let logoData = myWeakmap.get(myElement);
logoData.timesClicked++;
}, false);