一、Map的声明
Map是ES6中新增的一种有序的且唯一的数据结构。Map的声明需要用new关键字。Map中的参数必须是二维数组的形式,内层数组一般仅有两个值作为键值对,键值对必须是引用类型或者数字类型。如果是字符串需要加引号,否则报错。形如:
var m1 = new Map([['name', 'zs'], ['name', 'ls'], ['age', 13], ['sex', 'man']]);
console.log(m1);
二、Map的常用方法和属性
Map的原型上挂载了许多方法和属性,下文将对常用的方法和属性进行分析。
console.log(Map.prototype);
1.set()方法
set()方法相当于set中的add()方法,用于向集合中添加元素,当参数为一个值时,参数作为键名,有两个参数时,作为键值对。参数为Map中已有的键名时,则会修改对应的value值。参数为引用类型或者数字类型。
var m1 = new Map();
m1.set('name');
m1.set(function f1() { }, 18);
m1.set('sex', 'man');
m1.set({},{})
console.log(m1);;
2.get()方法
get()方法用于获取Map中key对应的value值,方法的参数为key值。返回值为获取到的value值,否则为undefined
var m1 = new Map();
m1.set('name');
m1.set(function f1() { }, 18);
m1.set('sex', 'man');
m1.set('sex', 'woman');
m1.set({}, {})
m1.set(1, 2)
console.log(m1);
console.log(m1.get('sex'));
console.log(m1.get(1));
console.log(m1.get(function f1() { }));
console.log(m1.get({}));
可以看到,获取到了sex与1的value值,为woman和2。而却获取不到函数f1和空对象的value值,这是因为get方法参数中的引用类型和map中的引用类型长相(值)虽然一致,但是他们的地址却不相同。简单地说,他们并不是同一个引用类型。所以获取不到。
3.delete()方法
方法参数为key值,用于删除对应的键值对。删除成功/失败返回t/f
var m1 = new Map();
m1.set('name');
m1.set(function f1() { }, 18);
m1.set('sex', 'man');
m1.set('sex', 'woman');
m1.set({}, {})
m1.set(1, 2)
console.log(m1);
console.log(m1.delete('sex'));
console.log(m1);
console.log(m1.delete('2'));
4.has()方法
var m1 = new Map();
m1.set('name');
m1.set(function f1() { }, 18);
m1.set('sex', 'man');
m1.set('sex', 'woman');
m1.set({}, {})
m1.set(1, 2)
console.log(m1);
console.log(m1.has('name'));
console.log(m1.has('2'));
has(key)方法用于判断map中是否含有名为key的键值对,返回值为T/F
5.entries(),forEach(),values(),keys() size
以上方法用于对map进行遍历。size属性为map的长度。map是一个可遍历的数据类型,这是因为其原型上挂载了[Symbol.iterator]方法。entries()返回包含键值对的迭代器,values()返回包含value值的迭代器,keys()返回包含key值的迭代器。可以配合for…of进行遍历。forEach()方法可对其value值进行遍历。
var m1 = new Map();
m1.set('name');
m1.set(function f1() { }, 18);
m1.set('sex', 'man');
m1.set('sex', 'woman');
m1.set({}, {})
m1.set(1, 2)
console.log(m1);
console.log(m1.size);
for (x of m1.entries()) {
console.log(x);
}
console.log(m1.size);
for (x of m1.keys()) {
console.log(x);
}
console.log(m1.size);
for (x of m1.values()) {
console.log(x);
}
m1.forEach(item => {
console.log(item);
});
6.clear()方法
clear()方法用于清空map
var m1 = new Map();
m1.set('name');
m1.set(function f1() { }, 18);
m1.set('sex', 'man');
m1.set('sex', 'woman');
m1.set({}, {})
m1.set(1, 2)
console.log(m1);
console.log(m1.size);
m1.clear();
console.log(m1.size);
console.log(m1);
三、WeakMap
WeakMap也是ES6中新增的数据类型,是Map的一种。它和map有以下区别:
1.WeakMap的key值必须是引用类型
var m1 = new WeakMap([[function f1() { }, '我是函数']]);
console.log(m1);
var m2 = new WeakMap([['name', 'zs']]);
console.log(m2);
2.WeakMap的方法参数也必须是引用类型
WeakMap的方法参数也必须是引用类型,否则报错。用set方法来举例。
var m1 = new WeakMap([[function f1() { }, '我是函数']]);
m1.set({ obj: 18 }, 'zs')
console.log(m1);
m1.set('name', 'zs');
3.WeakMap的方法和属性
WeakMap上只有delete,get,has,set方法,上文中提到这些方法的参数也必须是引用类型。WeakMap的原型上没有[Symbol.iterator]方法与size属性,所以不能进行遍历。当然,它的原型上也并没有entries,keys等返回迭代器的方法。
console.log(WeakMap.prototype);
4.如何获取WeakMap类型中的value值
上文中提到,WeakMap类型的key值必须是引用类型,其方法中的参数也必须是引用类型。而方法中参数和WeakMap中key值长相一致但并不指向同一地址,理论上这些方法会无效,那么如何解决呢?
这时候需要先把WeakMap中的key值传递给一个变量,然后将此变量放到WeakMap中,调用get()方法时,参数也写成该变量。这时候get()方法中的参数和WeakMap中的key长相一致并且也指向了同一地址。
var obj = { name: 18 }
var m1 = new WeakMap([[obj, '我是可获取的value值'], [function fn1() { }, 2]]);
console.log(m1.get(function fn1() { }));
console.log(m1.get(obj));