es6 — Map && WeakMap - 2019-01-10

  • 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)问题有解决,当我们扩展别人的库时,如果使用对象作为键名,就不用担心自己的属性与别人的相同

你可能感兴趣的:(es6 — Map && WeakMap - 2019-01-10)