Map和普通对象有什么区别
先来看看Map的定义: Map对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值)都可以作为一个键或一个值
- Map: 的key是有序的,因此,当迭代的时候,一个
Map
对象以插入的顺序返回键值。 - Object: 一个
Object
的键是无序的 - Map: 一个
Map
的键可以是任意值,包括函数、对象或任意基本类型。 - Object:
Object
的键只能是字符串和Symbol 下面是示例
const obj = { id: 1 };
const info = {};
info[obj] = "danceli";
console.log(info)
//结果为: [object Object]: "danceli"
// 为什么会有[object Object] 是因为执行了Object.prototype.toString.call(obj)返回了[object Object]所以对象的键值为这个字符串
//Map
const key1 = {};
const key2 = function() {};
const key3 = []
const map = new Map();
map.set(key1, "1");
map.set(key2, "2");
map.set(key3, "3");
map.set(Symbol("4"), "4");
console.log(map)
// Map的键值可以为任意值
Map的方法
- Map.prototype.clear()
clear()
方法会移除Map对象中的所有元素。 - Map.prototype.delete()
delete
方法用于移除Map
对象中指定的元素。map.delete(key) - Map.prototype.entries()
entries()
方法返回一个新的包含[key, value]
对的Iterator
对象,返回的迭代器的迭代顺序与Map
对象的插入顺序相同。
const map = new Map();
map.set("name", "danceli");
map.set({name: "danceli"}, "12");
const iter = map.entries()
console.log(iter.next()) //{ value: ['name', 'danceli'] }
- Map.prototype.forEach 会对该方法按照插入顺序进行key,value的遍历
function logMapEle(value, key, map) {
console.log(`map${key} => ${value}`);
}
new Map([["name", "li"], [NaN, "nan"]]).forEach(logMapEle)
- Map.prototype.get
get()
方法返回某个Map
对象中的一个指定元素。 - Map.prototype.has(key) 用来检测是否存在指定元素的键值
- Map.prototype.keys()
keys()
返回一个引用的Iterator
对象。它包含按照顺序插入Map
对象中每个元素的key值。 - Map.prototype.values()
values()
返回一个引用的Iterator
对象。它包含按照顺序插入Map
对象中每个元素的value值。 - Map.prototype.set
set()
方法为Map
对象添加或更新一个指定了键(key
)和值(value
)的(新)键值对。
WeakMap
对象是一组键/值对的集合,其中的键是弱引用的。其键必须是对象,而值可以是任意的。
WeakMap的用处
先看一个例子
const oBtn1 = document.querySelector(".btn1");
const oBtn2 = document.querySelector(".btn2");
function handleBtn1Click() {
}
function handleBtn2Click() {
}
oBtn1.addEventListener("click", handleBtn1Click, false);
oBtn2.addEventListener("click", handleBtn2Click, false);
//如果此时我需要删除这两个按钮元素, 但是他俩绑定了事件处理函数,事件处理函数没有销毁,还存在内存中
oBtn1.remove();
oBtn2.remove();
// 只能通过手动销毁
handleBtn1Click = null;
handleBtn2Click = null;
此时如果我们使用WeakMap就可以更方便
const oBtn1 = document.querySelector(".btn1");
const oBtn2 = document.querySelector(".btn2");
function handleBtn1Click() {
}
function handleBtn2Click() {
}
const map = new WeakMap()
//WeakMap的键名为弱引用,如果别人吧oBtn1或者oBtn2删除了,那么WeakMap里面对应的键名会被回收掉,键名回收掉之后键值也会回收掉
map.set(oBtn1, handleBtn1Click)
map.set(oBtn2 handleBtn2Click)
oBtn1.addEventListener("click", map.get(oBtn1), false);
oBtn2.addEventListener("click", map.get(oBtn2), false);
oBtn1.remove();
oBtn2.remove();
Set
Set
对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用
// 因为Set中的元素是唯一的所以常用来做数组去重
const arr = [1,2,1,2,3,4,5,7,5,4];
const set = new Set([...arr]);
Set
的方法和Map的大概相似,不在多说
WeakSet vs Set的差异
- WeakSet只能存储对象,而Set可以存储任意数据类型
- WeakSet存储的对象,如果没有其他的引用的话,这个对象将会被垃圾回收。这就是冠以 Weak 的原因,同时也意味着,WeakSet是不可枚举的,也就没有size。