Set
/* 具有相同的构造属性 ["name","length","prototype"] */
Object.getOwnPropertyNames(Set);
Object.getOwnPropertyNames(Map);
Object.getOwnPropertyNames(WeakSet);
复制代码
// 实例方法
Object.getOwnPropertyNames(Set.prototype); // => ["constructor", "has", "add", "delete", "clear", "entries", "forEach", "size", "values", "keys"]
复制代码
constructor()
size
返回实例成员数,有无 size 属性是其能否遍历的重要参考has()
add()
const item = new Set([1,1,2,2,3,4,5]);
const array = Array.from(item); // [1,2,3,4,5]
// 等效于
const array = [...item]; // ... 扩展运算符内部使用了 for...of 循环
复制代码
forEach((value, key, Set) => {}, bind)
使用回调函数遍历每个成员,Set的遍历顺序就是插入顺序keys()
返回健名的遍历器,Set 结构没有键名,只有键值,所以其行为和values()
一样values()
返回键值的遍历器entries()
返回键值对的遍历器delete()
clear()
没有返回值
Set.prototype[Symbol.iterator] === Set.prototype.values; // true
// 可以用 for...of 遍历 Set
for (const of set) {
}
复制代码
Map
Map 中各种类型的值(包括对象、HTML元素等)都可以当做建,添加顺序即为遍历顺序,同一个键多次赋值,后面的会覆盖前面的
Object.getOwnPropertyNames(Map); // => ["length", "name", "prototype"]
Object.getOwnPropertyNames(Map.prototype); // => ["constructor", "get", "set", "has", "delete", "clear", "entries", "forEach", "keys", "size", "values"]
复制代码
constructor()
// 构造方式
const map = new Map([
['key1': 'value1'],
['key2': 'value2'],
]);
// 等效于 [...map.entries()]
[...map]; // => [['key1', 'value1'], ['key2', 'value2']];
// 使用 Set 实例作为 Map 实例化传参
const set = new Set([
['foo', 1],
['bar', 2]
]);
const m = new Map(set);
复制代码
size
map.size; // => 2
复制代码
forEach((value, key, map) => {}, bind)
keys()
map.keys; // => MapIterator {"key1", "key2"}
[...map.keys()]; // => ['key1', 'key2'];
复制代码
values()
map.values(); // => MapIterator {"value1", "value2"}
[...map.values()]; // => ['value1', 'value2'];
复制代码
entries()
是 Map 结构默认的遍历器接口(Symbol.iterator
属性)
map.entries(); // => MapIterator {"key1" => "value1", "key2" => "value2"}
[...map.entries()]; // => [['key1', 'value1'], ['key2', 'value2']];
for (const [key, value] of map.entries()) {}
// 等效于
for (const [key, value] of map) {}
复制代码
set()
支持链式调用,即返回对象本身
只有对同一个对象的引用,Map 结构才会视为同一个键 -0 和 0 严格相等,NaN 不严格相等,但是 Map 视为同一个键
// 塞进一个空key-value
map.set(); // => Map(3) {"key1" => "value1", "key2" => "value2", undefined => undefined}
map.set(['arr'], [1, 2, 3]); // Map(4) {"key1" => "value1", "key2" => "value2", undefined => undefined, Array(1) => Array(3)}
复制代码
get()
找不到返回undefined
const map = new Map();
/* 下面这样是取不到值的,因为上面说了key要是同一个引用 */
map.set(['a'], 555);
map.get(['a']); // => undefined
/* 只有内存地址一致,才会被视为一个键 */
const k1 = ['str'];
const k2 = ['str'];
map
.set(k1, 'v1')
.set(k2, 'v2');
map.get(k1); // => 'v1'
map.get(k2); // => 'v2'
/* 只有下面这样赋/取值才有效 */
const k1 = ['b'];
map.set(k1, 666);
map.get(k1); // 666
/* 特殊类型 */
/* +0与-0 */
+0 === -0; // => true
map.set(+0, 'zero');
map.get(-0); // => 'zero'
const zero1 = +0;
const zero2 = -0;
map.get(zero1); // => 'zero'
map.get(zero2); // => 'zero'
/* NaN */
NaN === NaN; // => false
map.set(NaN, 'NaN');
mao.get(NaN); // => 'NaN'
const nan = NaN;
map.get(nan); // => 'NaN'
/* null 与 undefined */
null === undefined; // => false
map.set(null, 'empty');
const nu = null;
const ni = undefined;
map.get(nu); // => 'empty'
map.get(ni); // => undefined
复制代码
has()
map.has(nu); // => true
复制代码
delete()
返回true
或false
map.delete(nu); // => true
// 删除不存在的key返回false
map.delete(nu); // => false
复制代码
clear()
清除所有成员,无返回值
map.clear(); // => undefined
map; // => Map(0) {}
map.size; // => 0
复制代码
WeakSet
只能放对象(数组或类数组)的 Set,适合存放一些临时性的对象,因为(键名)弱引用的原因,其是不可遍历的。
Object.getOwnPropertyNames(WeakSet.prototype);
复制代码
constructor()
has()
add()
// 将 a 的成员作为 WeakSet 的实例对象的成员,而非数组对象本身
const a = [[1, 2], [3, 4]];
const wd = new WeakSet(a); // WeakSet {[1,2], [3,4]}
复制代码
delete()
Example
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
// Union
let union = new Set([...a, ...b]); // Set {1,2,3,4}
// Intersect
let intersect = new Set([...a].filter(x => b.has(x))); // Set {2,3}
// Difference
let difference = new Set([...a].filter(x => !b.has(x))); // Set {1}
// 改变原来结构
a = new Set([...a].map(i => i*2));
// 等效于
a = new Set(Array.form(set, i => i * 2));
// ???
const foos = new WeakSet()
class Foo {
constructor() {
foos.add(this)
}
method () {
if (!foos.has(this)) {
throw new TypeError('Foo.prototype.method 只能在Foo的实例上调用!');
}
}
}
//
const map0 = new Map()
.set(1, 'a')
.set(2, 'b')
.set(3, 'c');
const map1 = new Map(
[...map0].filter(([k, v]) => k < 3)
); // Map {1 => 'a', 2 => 'b'}
map1.get(1); // 'a'
复制代码