Map
Javascript的对象(Object),本质上是键值对的集合(Hash结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制,为了解决这个问题,ES6提供了Map数据结构,它类似于对象,也是键值对的集合,但是,键的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object结构提供了“字符串-值”的对应,Map结构提供了“值-值”的对应,是一种更完善的Hash结构实现。
创建Map
let map = new Map()
map.set('jack',18)
map.set('ross',20)
console.log(map)
Map也可以接受数组作为参数。
let map = new Map([
['name','张三'],
['title','Author']
])
map.size
map.has('name')
map.get('name')
map.has('title')
map.get('title')
如果对同一个键多次赋值,后面的值会覆盖掉前面的值
let map = new Map();
map
.set(1,'aaa')
.set(1,'bbb')
map.get(1) // 'bbb'
实例的属性和操作方法
1、size属性:size属性返回map结构的成员总数
let map = new Map();
map.set('foo',true),
map.set('bar',false);
map.size //2
2、set(key,value) :set方法设置key所对应的键值,然后返回整个Map结构,如果key已经有值,则键值会被更新,否则就新成该键。
var m = new Map();
m.set("edition", 6) // 键是字符串
m.set(262, "standard") // 键是数值
m.set(undefined, "nah") // 键是undefined
//set方法返回的是Map本身,可以采用链式写法
let map = new Map()
.set(1, 'a')
.set(2, 'b')
.set(3, 'c');
3、get(key):get方法获取key对应的键值,如果找不到key,返回undefined
var m = new Map();
var hello = function() {console.log("hello");}
m.set(hello, "Hello ES6!") // 键是函数
m.get(hello) // Hello ES6!
4、has(key):has方法返回一个布尔值,表示某个键是否在Map数据结构中
let m = new Map()
m.set('name','jack')
m.has('name') // true
m.has('age') // false
5、delete(key): delete方法删除某个键,返回true,如果删除失败,返回false。
var m = new Map();
m.set(undefined, "nah");
m.has(undefined) // true
m.delete(undefined)
m.has(undefined) // false
6、clear(): clear方法清除所有成员,没有返回值。
let map = new Map();
map.set('foo', true);
map.set('bar', false);
map.size // 2
map.clear()
map.size // 0
遍历方法
keys(): 返回键名的遍历器
values(): 返回键值的遍历器
entries(): 返回所有成员的遍历器
forEach(): 遍历Map的所有成员
let map = new Map([
['F', 'no'],
['T', 'yes'],
]);
for (let key of map.keys()) {
console.log(key);
}
// "F"
// "T"
for (let value of map.values()) {
console.log(value);
}
// "no"
// "yes"
for (let item of map.entries()) {
console.log(item[0], item[1]);
}
// "F" "no"
// "T" "yes"
// 或者
for (let [key, value] of map.entries()) {
console.log(key, value);
}
// 等同于使用map.entries()
for (let [key, value] of map) {
console.log(key, value);
}
与其他数据结构相互转换
1、Map转数组: Map转为数组,可以使用扩展运算符(...)
let map = new Map().set(true,7).set({foo:3},['abc'])
console.log([...map]) //[[true,7],[{foo: 3}, ['abc']]]
2、数组转map:将数组传入构造函数,就可以转为Map
let map = new Map([[true,7],[{foo: 3}, ['abc']]])
console.log(map) // {true => 7,{foo:3 } => ['abc']}
3、Map转对象:如果所有Map键都是字符串,它可以转为对象
function strMapToObj(strMap) {
let obj = Object.create(null);
for (let [k,v] of strMap) {
obj[k] = v;
}
return obj;
}
let myMap = new Map().set('yes', true).set('no', false);
strMapToObj(myMap) // {yes: true, no: false}
4、对象转为Map
function objToStrMap(obj) {
let strMap = new Map();
for (let k of Object.keys(obj)) {
strMap.set(k, obj[k]);
}
return strMap;
}
objToStrMap({yes: true, no: false})
//[ [ 'yes', true ], [ 'no', false ] ]
5、Map转JSON
Map转JSON分两种情况,一种是当Map的键都是字符串,这时可以选择转为对象JSON
function strMapToJson(strMap) {
return JSON.stringify(strMapToObj(strMap));
}
let myMap = new Map().set('yes', true).set('no', false);
strMapToJson(myMap) // '{"yes":true,"no":false}'
另一种情况是,Map的键名有非字符串,这时可以选择转为数组JSON
function mapToArrayJson(map) {
return JSON.stringify([...map]);
}
let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']);
mapToArrayJson(myMap) // '[[true,7],[{"foo":3},["abc"]]]'
6、JSON转Map
分两种情况,当所有键名都是字符串时:
function jsonToStrMap(jsonStr) {
return objToStrMap(JSON.parse(jsonStr));
}
jsonToStrMap('{"yes":true,"no":false}') // {'yes' => true, 'no' => false}
另一种情况,当整个JSON是一个数组,且每个数组成员本身,又是一个有两个成员的数组,这时,它可以一一对应地转为Map,这往往是数组转JSON的逆操作
function jsonToMap(jsonStr) {
return new Map(JSON.parse(jsonStr));
}
jsonToMap('[[true,7],[{"foo":3},["abc"]]]')
//{true => 7, Object {foo: 3} => ['abc']}