Map数据结构是为了解决对象无法使用非字符串作为键而提出的数据结构,本质上讲,Map是一个二维数组,其中数组元素是只含有两个元素的数组,这两个元素按顺序分别为键和值。如var m = new Map([[x, 1], [y, 2]]);
实际上,最常用的形式是把对象作为键,对象相关的信息作为值来存储在Map中。
-
设置键值对
设置键值对方法set(key, value);
var m = new Map(); var x = {id: 1}; m.set(x, 'foo');
获得值的方法get(key);m.get(x); // 'foo';
-
删除键值对
删除键值对的方法delete(key);m.delete(x);
清空所有数据则用clear()方法; -
构造Map
构造Map实例new Map(iterable); 参数是iterable对象。由于entries()方法产生的形式与Map本身一样,所以这里可以用Map实例当参数传入;var m2 = new Map(m.entries()); var m3 = new Map(m); // 等价于上面的形式;
当然,也可以直接传入二维数组的形式;
var m4 = new Map([[x, 1], [y, 2]]);
-
遍历Map
- 遍历键名:keys()方法,返回的是键名的迭代器,然后用for of循环遍历;
- 遍历值: values()方法,返回的是值的迭代器,然后用for of循环遍历;
- 遍历键值对: entries()方法,返回的是键值对上的迭代器;
- ForEach方法,类似于数组的ForEach方法;
转为数组的方法,可以直接用展开运算符…作用在iterable对象。如
var m = new Map();
var x = {id: 1}, y = {id: 2};
m.set(x, 'foo');
m.set(y, 'bar');
var marr = [...m];
var marr2 = [...m.entries()]; // 效果跟上面的一样;
console.log(marr); // [[{id: 1}, 'foo'], [{id: 2}, 'bar']]; 二维数组;
console.log(marr2[0][1]); // 'foo';
WeakMap是为了解决频繁变动对象垃圾回收(GC:garbage collector)而引入的Map弱引用数据结构。频繁变动的对象免得手动删除引用,而让GC自动回收。WeakMap的键只能是对象,且对象如果没有被其他对象所引用(即其他对象可以访问到),只有WeakMap可以引用到,则会被垃圾回收机制释放内存,相应的WeakMap的这一键值对会被删除。这一特点很适合于DOM对象,给DOM对象关联一些信息存储在WeakMap里,DOM对象一旦被删除,则其内存会被回收,WeakMap的这一键值对会消失。如:
var m = new WeakMap();
var x = {id: 1}, y = {id: 2}, z = {id: 3}, w = {id: 4};
m.set(x, y);
m.set(z, w);
x = null; // {id: 1}不再由变量x引用,只有m才能引用,此时,{id: 1}会被垃圾回收,这一键值对会被删除;
w = null; // 尽管值{id: 4}也不再由w引用,但m对值的引用是强引用,所以{id: 4}不会被回收;