【ES6基础】Map与WeakMap

ES6里除了增长了Set(集合类型)外(笔者在这篇文章《Set与WeakSet》有过介绍),今天这篇文章将介绍引入的新类型——Map(映射类型)及WeakMap。映射类型在计算机科学中定义属于关联数组,而关联数组的定义是若干键值对(Key/Value Pair)组成的集合,其中每一个Key值都只能出现一次。javascript

本篇文章将从如下方面进行介绍:前端

  • Map代码示例
  • Map经常使用方法示例
  • Map与Object的区别
  • weakMap介绍

本篇文章阅读时间预计5分钟java

Map代码示例

Map的键和值能够是任何数据类型,键值对按照插入顺序排列,若是插入重复的键值,后面的键值会覆盖前者,下段代码是个简单示例,演示了Map的一些用法:数组

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);
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复制代码

上述代码将会输出bash

true
A
[ { n: 1 }, 'A' ] [ '2', 9 ]
Map { { n: 1 } => 'A', '2' => 9 }
2复制代码

从上述代码中,咱们能够看出使用new Map()语法进行声明,map键的类型可使用任意对象做为键(字符串,object类型,functions),咱们直接二维数组键值对的形传入到构建函数中,第一项为键,后一项为值。微信

const map=new Map([['foo',1],['foo',2]])
console.log(map);
console.log(map.get('foo'))复制代码

上述代码将会输出:函数

Map { 'foo' => 2 }
2复制代码

上述代码咱们能够看出,若是存在相同的键,则会按照FIFO(First in First Out,先进先出)原则,后面的键值信息会覆盖前面的键值信息。post

Map经常使用方法示例

如下表格罗列了Map相关的方法ui

操做方法this

内容描述

map.set(key,value)

添加键值对到映射中

map.get(key)

获取映射中某一个键的对应值

map.delete(key)

将某一键值对移除映射

map.clear()

清空映射中全部键值对

map.entries()

返回一个以二元数组(键值对)做为元素的数组

map.has(key)

检查映射中是否包含某一键值对

map.keys()

返回一个当前映射中全部键做为元素的可迭代对象

map.values()

返回一个当前映射中全部值做为元素的可迭代对象

map.size

映射中键值对的数量

增删键值对与清空MAP

let user={name:"Aaron",id:1234};
let userHobbyMap=new Map();
userHobbyMap.set(user,['Ice fishing','Family Outting']);//添加键值对
console.log(userHobbyMap);
userHobbyMap.delete(user);//删除键值对
userHobbyMap.clear(); //清空键值对
console.log(userHobbyMap);复制代码

上述代码将会输出:

Map { { name: 'Aaron', id: 1234 } => [ 'Ice fishing', 'Family Outting' ] }
Map {}复制代码

获取键值对

与Set集合对象不同,集合对象的元素没有元素位置的标识,故没有办法获取集合某元素,可是映射对象由键值对组成,因此能够利用键来获取对应的值。

const map=new Map();
map.set('foo', 'bar');
console.log(map.get('foo')); //output bar复制代码

检查映射对象中是否存在某键

与Set集合同样,Map映射也可使用has(键)的方法来检查是否包含某键。

const map=new Map([['foo',1]])
console.log(map.has('foo'));//output true
console.log(map.has('bar'));//output false复制代码

遍历映射中的键值对

映射对象在设计上一样也是一种可迭代的对象,能够经过for-of循环对其遍历,同时也可使用foreach进行遍历。 映射对象中带有entries()方法,用于返回包含全部键值对的可迭代的二元数组对象,而for-of和foreach即是先利用entries()方法先将映射对象转换成一个类数组对象,然年再进行迭代。

const map=new Map([['foo',1],['bar',2]]);
console.log(Array.from(map.entries()));
//output
//[ [ 'foo', 1 ], [ 'bar', 2 ] ]
for(const [key,value] of map){
    console.log(`${key}:${value}`);
}
//output
//foo:1
//bar:2
map.forEach((value,key,map)=>
  console.log(`${key}:${value}`))
//output
//foo:1
//bar:2复制代码

Map与Object的区别

说了这么多映射对象的方法,Map和Object对象有哪些区别呢,如下表格进行了总结:

对比项

映射对象Map

Object对象

存储键值对

遍历全部的键值对

检查是否包含指定的键值对

使用字符串做为键

使用Symbol做为键

使用任意对象做为键

能够很方便的得知键值对的数量

从中咱们能够看出Map对象可使用任何对象做为键,这就解决了咱们实际应用中一个很大的痛点,好比如今一个DOM对象做为键时,Object就不是那么好用了。

WeakMap

与集合类型(Set)同样,映射类型也有一个Weak版本的WeakMap。WeakMap和WeakSet很类似,只不过WeakMap的键会检查变量的引用,只要其中任意一个引用被释放,该键值对就会被删除。

如下三点是Map和WeakMap的主要区别: 1.Map对象的键能够是任何类型,但WeakMap对象中的键只能是对象引用 2.WeakMap不能包含无引用的对象,不然会被自动清除出集合(垃圾回收机制)。 3.WeakSet对象是不可枚举的,没法获取大小。

下段代码示例验证了WeakMap的以上特性:

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 }
keyObject=null;
console.log(weakmap.has(keyObject));
//output false复制代码

小节

今天的内容就介绍到这里,咱们明白了Map是一个键值对的映射对象,相比Object来讲可使用任何键作为键值,而且可以很方便的获取键值对。WeakMap相对于Map是一个不可枚举的对象,必须使用对象做为键值。如何更好的使用Map和WeakMap还须要具体结合咱们实际的业务场景进行灵活使用。

相关文章
相关标签/搜索