Map的用法一
1.Map的含义和基本用法#
Javascript的对象(Object),本质上是键值对的集合(hash结构),但是传统上只能用字符当作键。这给它的使用带来了很大的限制。
上面代码原意是将一个DOM节点作为对象data的键,但是由于对象只接受字符串作为键名,所以element被自动转换为字符串[object HTMLDivElement]。
为了解决这个问题,ES6提供了Map数据结构。它类似于对象,也是键值对的集合,但是 “键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object结构提供了“字符串一值”的对应,Map结构提供了“值一值”的对应,是一种更完善的Hash结构的实现。如果你需要“键值对”的数据结构,Map比Object更适合。
上面代码使用Map结构的Set方法,将对象o当作m的一个值,然后又使用get方法读取这个键,接着使用delete方法删除这个键。
上面的例子展示了如何向Map添加成员。作为构造函数,Map也可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。
上面代码在新建Map实例时,就指定了两个键name和title。
Map构造函数接受数组作为参数,实际上执行的是下面的算法。
实际上,不仅仅是数组,任何具有Iterator接口、且每个成员都是一个双元素的数组的数据结构都可以当作Map构造函数的参数。这就是说,Set和Map都可以用来生成新的Map。
上面代码中,我们分别使用Set对象和Map对象,当作Map构造函数的参数,结果都生成了新的Map对象。
如果对同一的键多次赋值后,后面的值将覆盖前面的值。
上面代码对键1连续赋值两次,后一次的值会覆盖前一次的值。
如果读取一个未知的键,则会返回undefined。
注意:只有对同一个对象的引用,Map结构才将其视为同一个键。这一点要非常小心。
上面的代码的set和get方法,表面是针对同一个键,但实际上这是两个不同的数组实例。内存地址是不一样的,因此get方法无法读取该键,返回undefined。
同理,同样的值的两个实例,在Map结构中被视为两个键。
上面代码中,变量k1和k2的值是一样的,但是它们在Map结构中被视为两个键。
由上可知,Map的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。这就解决了同名属性碰撞(clash)的问题,我们扩展别人的库的时候,如果使用对象作为键名,就不用担心自己的属性与原作者的属性名。
如果Map的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map将其视为一个键,比如0和-0就是一个键,布尔值true和字符串true则是两个不同的键。另外,undefined和null也是两个键。虽然NaN不严格相等于自身,但Map将其视为一个键。
(参考ECMAScript 6入门)