ES6 温故知新 Set & Map
2020-02-23 本文已影响0人
滑天下之大稽
Set
ES6 提供了新的数据结构 Set
。它类似于数组,但是成员的值都是唯一的,没有重复的值。
Set
在 ES6 中的定义:
interface SetConstructor {
new <T = any>(values?: readonly T[] | null): Set<T>;
readonly prototype: Set<any>;
}
declare var Set: SetConstructor;
通过 new
创建一个 Set 集合:
const s = new Set();
const s = new Set([1, 2, 3, 4]);
Set
接受一个由任意类型的数组作为参数,一个Set集合。
interface Set<T> {
add(value: T): this;
clear(): void;
delete(value: T): boolean;
forEach(callbackfn: (value: T, value2: T, set: Set<T>) => void, thisArg?: any): void;
has(value: T): boolean;
readonly size: number;
}
- 方法:
-
add
添加某个值,返回set
本身; -
clear
清空set
所有元素,没有返回值; -
delete
删除某个值,返回一个boolean
,表示删除是否成功; -
has
返回一个布尔值,表示set
是否有该成员;
-
- 属性:
-
size
返回set
实例的成员总数。
-
WeakSet
WeakSet
结构与 Set
类似,也是不重复的值的集合。但是WeakSet 的成员只能是复杂类型的值(或继承自 object
)。
WeakSet 中的对象都是弱引用,即垃圾回收机制不考虑 WeakSet 对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于 WeakSet 之中。
interface WeakSetConstructor {
new <T extends object = object>(values?: readonly T[] | null): WeakSet<T>;
readonly prototype: WeakSet<object>;
}
定义一个 WeakSet
:
const ws = new WeakSet();
const ws = new WeakSet([[1, 2], [3, 4]]);
ws.add(1); // TypeError: Invalid value used in weak set
WeakSet
没有 size
属性,没有办法遍历它的成员。
interface WeakSet<T extends object> {
add(value: T): this;
delete(value: T): boolean;
has(value: T): boolean;
}
WeakSet
有三个方法:
-
add
向 weakset 中增加一个新成员。 -
delete
清除 WeakSet 实例的指定成员。 -
has
返回一个布尔值,表示某个值是否在WeakSet
实例之中。
Map
interface MapConstructor {
new(): Map<any, any>;
new<K, V>(entries?: readonly (readonly [K, V])[] | null): Map<K, V>;
readonly prototype: Map<any, any>;
}
Map
类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
const m = new Map();
const o = {p: 'Hello World'};
m.set(o, 'content') // 使用o作为Map的一个键值,其value是‘content’
m.get(o) // "content"
m.has(o) // true
m.delete(o) // true
m.has(o) // false
interface Map<K, V> {
clear(): void;
delete(key: K): boolean;
forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void;
get(key: K): V | undefined;
has(key: K): boolean;
set(key: K, value: V): this;
readonly size: number;
}
-
Map
的属性:-
size
返回Map
结构的成员总数。
-
-
Map
的方法:-
clear
清楚Map
所有的成员,返回空; -
delete
删除Map
指定Key
的成员,返回是否删除成功; -
get
获取指定Key
的成员的Value
,没有该Key
则返回undefined
; -
has
方法返回一个布尔值,表示某个键是否在当前Map
对象之中。 -
set
方法设置键名key
对应的键值为value
,然后返回整个Map
结构。如果key
已经有值,则键值会被更新,否则就新生成该键。
-
-
Map.prototype.keys()
:返回键名的遍历器。 -
Map.prototype.values()
:返回键值的遍历器。 -
Map.prototype.entries()
:返回所有成员的遍历器。 -
Map.prototype.forEach()
:遍历 Map 的所有成员。
WeakMap
WeakMap
与 Map 类似,但是WeakMap
只接受对象作为键名
interface WeakMapConstructor {
new <K extends object = object, V = any>(entries?: readonly [K, V][] | null): WeakMap<K, V>;
readonly prototype: WeakMap<object, any>;
}
WeakMap
与Map
在 API 上的区别主要是两个,一是没有遍历操作(即没有keys()
、values()
和entries()
方法),也没有size
属性。
interface WeakMap<K extends object, V> {
delete(key: K): boolean;
get(key: K): V | undefined;
has(key: K): boolean;
set(key: K, value: V): this;
}
-
delete
删除Map
指定Key
的成员,返回是否删除成功; -
get
获取指定Key
的成员的Value
,没有该Key
则返回undefined
; -
has
方法返回一个布尔值,表示某个键是否在当前Map
对象之中。 -
set
方法设置键名key
对应的键值为value
,然后返回整个Map
结构。如果key
已经有值,则键值会被更新,否则就新生成该键。
Map 与其他值的互相转换:
-
Map => Array: 使用扩展运算符
...
const m = new Map().set(true, 7).set({foo: 3}, ['abc']); [...m] // [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ]
-
Array => Map: 将数组传入 Map 构造函数,就可以转为 Map。
-
Map => Object:如果有非字符串的键名,那么这个键名会被转成字符串,再作为对象的键名。
function mapToObj(m) { let obj = Object.create(null); for (let [k,v] of m) { obj[k] = v } return obj } const myMap = new Map() .set('yes', true) .set('no', false); console.log(mapToObj(myMap)); // { yes: true, no: false }
-
Object => Map:
let obj = {"a":1, "b":2}; let map = new Map(Object.entries(obj));
-
Map => JSON:
-
Key 都为 字符串
function strMapToJson(strMap) { return JSON.stringify(strMapToObj(strMap)); } let myMap = new Map().set('yes', true).set('no', false); strMapToJson(myMap) // '{"yes":true,"no":false}'
-
Key 为其他值
function mapToArrayJson(map) { return JSON.stringify([...map]); } let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']); mapToArrayJson(myMap) // '[[true,7],[{"foo":3},["abc"]]]'
-
-
JSON => Map:
function jsonToStrMap(jsonStr) { return objToStrMap(JSON.parse(jsonStr)); } jsonToStrMap('{"yes": true, "no": false}')