Map和WeakMap
- 使用new Map()语法进行声明,Map键的类型可以使用任意对象作为键(字符串,object类型),我们还可以直接以二维数组键值对的形传入到构建函数中,第一项为键,后一项为值
let map = new Map();
let o = { n: 1 };
map.set(o, "A"); //add
map.set("2", 9);
console.log(map.has("2")); //check if key exists
console.log(map.get(o)); //retrieve value associated with key
console.log(...map);
console.log(map);
console.log(map.entries()) //entries返回所有成员的迭代器
console.log(Array.from(map.entries()));
let kk = map.keys();
console.log(kk)
//迭代对象,通过next()循环,ifnext()为undefined就说明遍历完毕
//keys():返回键名的迭代器。
//values():返回键值的迭代器。
//entries():返回所有成员的迭代器。
//通过next()可以往后遍历,知道next()为空
console.log(kk.next())
console.log(kk.next())
map.delete("2"); //delete key and associated value
map.clear(); //delete everything
//create a map from iterable object
let map_1 = new Map([[1, 2], [4, 5]]);
console.log(map_1.size); //number of keys
//使用重复的键,如果存在相同的键,则会按照FIFO(First in First Out,先进先出)原则,后面的键值信息会覆盖前面的键值信息。
const map1 = new Map([['foo', 1], ['foo', 2]]);
console.log(map1);
console.log(map1.get('foo'));
WeakMap
WeakMap的设计目的在于,键名是对象的弱引用(垃圾回收机制不将该引用考虑在内),所以其所对应的对象可能会被自动回收。当对象被回收后,WeakMap自动移除对应的键值对。典型应用是,一个对应DOM元素的WeakMap结构,当某个DOM元素被清除,其所对应的WeakMap记录就会自动被移除。基本上,WeakMap的专用场合就是,它的键所对应的对象,可能会在将来消失。WeakMap结构有助于防止内存泄漏。
// 以下三点是Map和WeakMap的主要区别:
// Map对象的键可以是任何类型,但WeakMap对象中的键只能是对象引用
// WeakMap不能包含无引用的对象,否则会被自动清除出集合(垃圾回收机制)。
// WeakSet对象是不可枚举的,无法获取大小。
let weakmap = new WeakMap();
(function () {
let o = { n: 1 };
weakmap.set(o, "A");
})(); // here 'o' key is garbage collected
let s = { m: 1 };
weakmap.set(s, "B");
console.log(weakmap.get(s));
//console.log(...weakmap); // exception thrown
weakmap.delete(s);
//weakmap.clear(); // Exception, no such function
let weakmap_1 = new WeakMap([[{}, 2], [{}, 5]]); //this works
console.log(weakmap_1.size); //undefined”
// const weakmap = new WeakMap();
let keyObject = { id: 1 };
const valObject = { score: 100 };
weakmap.set(keyObject, valObject);
console.log(weakmap.get(keyObject));
//output { score: 100 }
//将引用设为null,无用的引用键,会被回收
keyObject = null;
console.log(weakmap.has(keyObject));
//output false