Open yaofly2012 opened 5 years ago
Map
Map
是key-value
的有序集合,其中key
可以是任意数据类型。
虽然规范里Map判断两个key是否相等采用同值相等算法,但是ES规范里0
和-0
是相等的,即本质采用的是0值相等
算法。
var s = new Map();
s.set(NaN, 1)
s.set(-0, 2);
s.has(NaN); // true
s.has(+0,); // true
key-value
集合,但是无序的,并且key
只能是字符串或者Symbol
,所以对象可以是视为属性集合;
当然了也没那么无序,见getOwnPropertyNames
key-value
集合,并且key
可以是任意类型的数据。MDN还详细总结了两者的区别,见Objects 和 maps 的比较。
两者通过key查找value的时间复杂度都是O(1)。
利用Object.entries
函数
var obj = {
name: 'join',
age: 22
}
var map = new Map(Object.entries(obj))
var map = new Map()
map.set('name', 'join');
map.set('age', 22)
map.set(() => {}, 'func')
var a = Object.fromEntries(map.entries())
obj.keys(a) // ["name", "age", "() => {}"]
因为Map的key可以是任意类型,在转对象过程中Object.fromEntries
函数会被引用类型的key转成字符串。
对象转key-value对的方法entries
是挂载到Object
上的静态方法,即Object.entries
,并且返回的是个数组。而Map确是个成员方法Map.prototype.entries
,并且返回的是个迭代器。
这样设计的动机是什么?
Map
等于两个数组!!!???用两个数组模拟Map
:一个数组用于存储key,另一个数组用于存储value。两个数组各元素一一对应。
但是这样无法实现通过key查找value的时间复杂度都是O(n)。性能肯定比Map
差远了。
Map
怎么实现的 TODOMap
如何实现的和一般的Hash表算法不同的是ES2015的Map有几个问题待解决:
下面的研究参考深入理解V8 Map的实现
不同类型的key采用不同的hash函数:
Symbol
类型:基于字符串内容计算Map
的V8采用C++实现Map
的目前实在看不懂源码(~囧~),只能看corejs的实现了。
采用确定性哈希表算法
WeakMap
跟Map
区别在于:
null
的对象;
var map = new WeakMap();
// TypeError: Invalid value used as weak map key
map.set(1, 12)
// TypeError: Invalid value used as weak map key
map.set(null, 12)
WeakMap
对象不是可迭代对象。
typeof WeakMap.prototype[Symbol.iterator] //"undefined"
native WeakMaps hold "weak" references to key objects, which means that they do not prevent garbage collection in case there would be no other reference to the key object. This also avoids preventing garbage collection of values in the map.
不影响JS引擎对key的GC。
WeakMap
对象不是可迭代对象WeakMap
对象的key可能随时被GC了。获取key列表是无意义的,所以 WeakMap
对象不是可迭代对象。
var map = new WeakMap();
// TypeError: map is not iterable
for(var i of map) {
console.log(i)
}
也是因为这个原因WeakpMap
没有遍历相关的方法(forEach
, entiries
, keys
, values
)并且还没有size
属性(size
属性也是无意义的)。
最后相对于Map
只剩下4个API了:
WeakMap
如果你要往对象上(key引用的对象)添加额外的数据,不想修改原对象(或则原对象根本就不可扩展),又不想干扰垃圾回收机制,就可以使用WeakMap
。
比如:
WeakMap
解决循环引用时记录已经Copy的对象。
Set
一、语法
1.1 功能
值的集合,并且值不能重复。数组也是值的集合,但是数组的元素可以是重复的。
1.2
Set
和数组数组转成
Set
new Set(array)
Set
转成数组Array.from
数组元素去重
注意:
Array.indexOf
和Set
使用的是不同的相等判断逻辑二、
Set
是如何实现的同
Map
的实现(下面会说),只不过Set
只有key,没有value。参考