- 2019-01-10 创建
目的
JavaScript的对象本质上是键—值对的集合,但是,只能用字符串作为键。这就有很多限制了。为了解决这个问题,ES6提供了Map数据结构
。它类似于对象,也是键—值对的集合,但‘键’的范围不限于字符串,各种类型的值(包括对象)都可以当做键。
也就是说对象提供字符串—值结构,Map提供值—值结构,Map结构是一种更完善的hash结构实现。
var m = new Map();
var o = {
p : 'hello'
};
m.set(o, 'content');
console.log(m.get(o)); // content
console.log(m.has(o)); // true
console.log(m.delete(o)); // true
console.log(m.has(o)); // false
作为构造函数,Map可以接受一个数组作为参数,该数组的成员表示的是一个个键值对的数组(相当于二维数组)
var map = new Map([['name','张三'],['age',21]]); // 接受一个数组,数组里的成员是一个个的数组,小数组里是key-value的组合
console.log(map.size); // 2
console.log(map.has('name')); // true
console.log(map.get('name')); // 张三
console.log(map.has('age')); // true
console.log(map.get('age')); // 21
如果对一个键多次赋值,后面的值将覆盖前面的值
let map = new Map();
map.set(1, 'aaa');
map.set(1, 'bbb');
console.log(map.get(1)); // bbb,说明后边的值将前边的覆盖掉了
console.log(new Map().get('ajkf')); // 读取未知的值,返回undefined
注意:
只有对同一对象的引用(引用类型),Map结构才会视为同一个键(键是复杂类型的值),而如果Map的键是一个简单类型的值(数字,字符串,布尔值),只要两个值严格相等,就视为同一个键.
var map = new Map();
map.set(['a'], 555);
console.log(map.get(['a'])); // undefined,set和get方法表面上是同一个键,实际上是两个值,他们的内存地址不一样,get无法读取该键,返回undefined
// 这里是简单类型,两者严格相等,所以就视为一个键
map.set('a',1);
console.log(map.get('a')); // 1
简单值的特例:NaN在Map中被视为同一个键,+0 -0也被视为同一个键
var map = new Map();
map.set(NaN, 124);
console.log(map.get(NaN)); // 124
map.set(+0, 12);
console.log(map.get(-0)); // 12
同理:同样的值的两个实例,在Map结构中被视为两个键(键是复杂类型的值)
var map = new Map();
var k1 = ['a'];
var k2 = ['b'];
map.set(k1,111);
map.set(k2,222);
console.log(map.get(k1)); // 111
console.log(map.get(k2)); // 222
总结
Map的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。这对于同名属性碰撞(clash)问题有解决,当我们扩展别人的库时,如果使用对象作为键名,就不用担心自己的属性与别人的相同
网友评论