语法
new Map([iterable])
参数: 可以是数组或者其他的可迭代对象. null 会被当作 undefined
Map 同 Set 类似, NaN 是相同的, 对象和数组是不同的.
- // 对象
- var data = {
- };
- var o = {
- a:1
- };
- data[o] = 222;
- console.log(data); // {
- [object Object]: 1
- }
上例中, 因为对象的 key 为字符串, 当为对象的时候, 自动转换成字符串 "[object Object]"
- let myMap = new Map([
- ['age',24],
- ['name','xixixi']
- ])
- myMap // {
- "age" => 24, "name" => "xixixi"
- }
- myMap.size // 2
Object 和 Map 比较
对象的键只能为字符串, 但是 Map 的键可以是任意值
可以通过 map.size 来获取 Map 的个数, 而 Object 必须要遍历来手动获取
Map.prototype.set() && Map.prototype.get()
set() 方法为 Map 对象添加一个指定键 (key) 和值 (value) 的新元素. 返回 Map 对象.
若已经存在键, 则更新键值, 否则, 重新建立新键
myMap.set(key, value);
get() 方法用来获取一个 Map 对象中指定的元素.
myMap.get(key);
参数: 必填
返回值为 Map 对象
- let obj = {
- a:1
- };
- let arr = [1]
- let arr2 = [1]
在 Map 中, 只有引用同一个对象, 才视为是同一个键;
- let map = new Map()
- .set(obj,'xixi') // 可用链式
- map.get(obj) // 'xixi'
- map.get({a:1}) //undefined obj 和 {a:1} 内存地址不一样, 所以找不到{a:1}
arr 和 arr2 虽然看似相同, 但是指向的指针并不同, 所以 Map 中也是区分他们不为同一个键
- map.set(arr,1111)
- .set(arr2,2222)
- get(arr) //1111
- map.get(arr2) //2222
若是同一个键被赋值了多次, 后面的会覆盖之前的值
- map.set(arr,'重新赋值');
- map.get(arr) // '重新赋值'
Map 对象将 0 -0 +0 视为同一个值
- map.set(-0,'0 相等');
- map.get(0); // 0 相等
- map.get(+0); // 0 相等
Map 视 NaN 相等
- map.set(NaN,'相等');
- map.get(Number('xixixi')) // '相等'
布尔值 true 和'true'是两个不同的键, undefined 和 null 也是两个不同的键
- map.set(true,111)
- map.set('true',222)
- map.set(undefined,333)
- map.set(null,444)
- map.get(undefined) // 333
- map.get(true) //111
- Map.prototype.has()
返回一个 bool 值, 用来表明 map 中是否存在指定元素.
myMap.has(key);
参数: 必需
返回值: 布尔值, 若存在于 Map 中, 则返回 true
- // 接以上案例
- map.has(arr) //true
- map.has([1]) //false
- Map.prototype.delete()
移除 Map 对象中指定的元素.
myMap.delete(key);
参数: 必需
返回值: 布尔值, 若为 true, 则删除成功
- map.delete(arr) //true
- map.has(arr) //false
- map.delete([1]) //false
- Map.prototype.clear()
清除所有成员, 没有返回值
- map.clear()
- map.size // 0
- Map.prototype.keys()
返回键名的遍历器
myMap.keys()
例子
- var map = new Map()
- .set('aa',11)
- .set('bb',22)
- for(let key of map.keys()){
- console.log(key)
- }
- //aa
- //bb
- Map.prototype.values()
返回键值的遍历器
myMap.values()
例子
- for(let value of map.values()){
- console.log(value)
- }
- //11
- //22
- Map.prototype.entries()
返回所有成员的遍历器
myMap.entries()
例子
- for(let item of map.entries()){
- console.log(item)
- }
- // ['aa',11]
- // ['bb',22]
- for(let [key,value] of map.entries()){
- console.log(key,value)
- }
- // aa 11
- // bb 22
- for (let [key,value] of map){
- console.log(key,value)
- }
- // 等同于 map.entries(); 结果和上一个相同
- Map.prototype.forEach()
- myMap.forEach(callback[, thisArg])
callback: 和 Set 类似, 有三个参数, 第一个为键值, 第二个为键名, 第三个为 Map,
thisArg:this, 可选
- var map = new Map()
- .set('aa',11)
- .set('bb',22)
- map.forEach(function (value,key,mymap){
- console.log(value,key,mymap)
- })
- // 11 "aa" {"aa" => 11, "bb" => 22}
- // 22 "bb" {"aa" => 11, "bb" => 22}
Map 和 数组
map 转数组
- var map = new Map()
- .set('aa',11)
- .set('bb',22)
- .set('cc',33)
- [...map] // [ ['aa',11],['bb',22],['cc',33] ]
- [...map.keys()] // ["aa", "bb", "cc"]
- [...map.values()] // [11, 22, 33]
- [...map.entries()] // [ ['aa',11],['bb',22],['cc',33] ]
数组转 map
- let myMap = new Map([
- ['age',24],
- ['name','xixixi']
- ])
Map 和 对象
map 转对象(map 中所有的键是字符串, 可以转对象)
- function mapToObj(myMap){
- let obj = Object.create(null);
- for(let [key,val] of myMap){
- obj[k] = v
- }
- return obj;
- }
对象转 Map
- function objToMap(obj){
- let map = new Map();
- for(let k in obj){
- map.set(k,obj[k])
- }
- return map;
- }
- WeakMap
类似 Map, 但是键必须是对象(null 除外), 值可以是任意值;
es5 做法
- let obj1 = {a:1,b:2};
- let obj2 = {a2:1,b2:2};
- let arr = [
- [obj1,'xixi'],
- [obj2,'haha']
- ]
arr 中引用了两个对象, 如果不需要这两个对象的时候, 我们就要手动删除 arr 中的引用, 否则垃圾回收机制不会释放 obj1,obj2 中的内存
- arr[0] = null;
- arr[1] = null;
es5 做法很麻烦, WeakMap 解决了这个问题. 他的键名对象都是弱引用,
即垃圾回收机制不将其考虑在内. 只要被引用的对象都被清除, 垃圾回收机制就会释放改对象所占的内存;
一旦不再需要, WeakMap 里面的键值对象和所对应的键值就会消失, 不需要再手动删除引用.
正是因为是弱引用, 所以内部的 key 不可枚举.
有助于防止内存泄漏.
WeakMap 弱引用的只有键名, 键值是正常引用
- let wm = new WeakMap();
- let key = {
- };
- let obj = {
- aa: 1
- };
- wm.set(key, obj);
- obj = null;
- wm.get(key) // {
- aa:1
- }
因为键值的引用是正常引用, 即使外部已经消除了 obj 的引用, 但是内部键值的引用依然存在.
只有 set() ;get() ;has(); delete() 四种方法, 无 size 属性
来源: http://www.jianshu.com/p/5a84bf3a7a80