es6学习笔记8--Map数据结构
MapMap结构的目的和基本用法JavaScript的对象(Object),本质上是键值对的集合(Hash结构),但是只能用字符串当作键。这给它的使用带来了很大的限制。 var data = {}; var element = document.getElementById("myDiv"); data[element] = metadata; data["[Object HTMLDivElement]"] // metadata 上面代码原意是将一个DOM节点作为对象data的键,但是由于对象只接受字符串作为键名,所以element被自动转为字符串 为了解决这个问题,ES6提供了Map数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object结构提供了“字符串—值”的对应,Map结构提供了“值—值”的对应,是一种更完善的Hash结构实现。如果你需要“键值对”的数据结构,Map比Object更合适。 var m = new Map(); var o = {p: "Hello World"}; m.set(o,"content") m.get(o) "content" m.has(o) true m.delete(o) true m.has(o) false 上面代码使用set方法,将对象o当作m的一个键,然后又使用get方法读取这个键,接着使用delete方法删除了这个键。 作为构造函数,Map也可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。 var map = new Map([["name","张三"],["title","Author"]]); map.size 2 map.has("name") true map.get("name") "张三" map.has("title") true map.get("title") "Author" 上面代码在新建Map实例时,就指定了两个键 注意,只有对同一个对象的引用,Map结构才将其视为同一个键。这一点要非常小心。 Map(); map.set(['a'],555); map.get(['a']) undefined 上面代码的 同理,同样的值的两个实例,在Map结构中被视为两个键。 Map(); var k1 = ['a']; var k2 = ['a']; map .set(k1,111) .set(k2,222); map.get(k1) 111 map.get(k2) 222 上面代码中,变量 由上可知,Map的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。这就解决了同名属性碰撞(clash)的问题,我们扩展别人的库的时候,如果使用对象作为键名,就不用担心自己的属性与原作者的属性同名。 如果Map的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map将其视为一个键,包括0和-0。另外,虽然NaN不严格相等于自身,但Map将其视为同一个键。 let map = Map(); map.set(NaN,123); map.get(NaN) 123 map.set(-0,123); map.get(+0) 123 实例的属性和操作方法Map结构的实例有以下属性和操作方法。 (1)size属性
(2)set(key,value)
(3)get(key)
(4)has(key)
(5)delete(key)
(6)clear()
遍历方法Map原生提供三个遍历器生成函数和一个遍历方法。
等同于使用map.entries() for (let [key,value] of map) { console.log(key,value); } 上面的那个例子,表示Map结构的默认遍历器接口( map[Symbol.iterator] === map.entries true Map结构转为数组结构,比较快速的方法是结合使用扩展运算符(...)。 WeakMap
WeakMap() map.set(1,2) TypeError: 1 is not an object! map.set(Symbol(),1)"> TypeError: Invalid value used as weak map key 上面代码中,如果将
下面是 var wm = WeakMap(); var element = document.querySelector(".element"); wm.set(element,"Original"); wm.get(element) "Original" element.parentNode.removeChild(element); element = null; wm.get(element) undefined 上面代码中,变量 WeakMap与Map在API上的区别主要是两个,一是没有遍历操作(即没有 WeakMap的另一个用处是部署私有属性。 let _counter = WeakMap(); let _action = WeakMap(); class Countdown { constructor(counter,action) { _counter.set(this,counter); _action.set(); if (counter < 1) return; counter--; _counter.set(if (counter === 0) { _action.get()(); } } } let c = new Countdown(2,() => console.log('DONE')); c.dec() c.dec() DONE 上面代码中,Countdown类的两个内部属性 ? ? ? ? ? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |