带键的集合
映射
Map对象
ECMAScript 2015 引入了一个新的数据结构来将一个值映射到另一个值。一个Map对象就是一个简单的键值对映射集合,可以按照数据插入时的顺序遍历所有的元素。
下面的代码演示了使用Map进行的一些基本操作。请参考Map以获取更多的样例和完整的 API。你可以使用for...of循环来得到所有的[key, value]。
js
var sayings = new Map();
sayings.set('dog', 'woof');
sayings.set('cat', 'meow');
sayings.set('elephant', 'toot');
sayings.size; // 3
sayings.get('fox'); // undefined
sayings.has('bird'); // false
sayings.delete('dog');
sayings.has('dog'); // false
for (var [key, value] of sayings) {
console.log(key + ' goes ' + value);
}
// "cat goes meow"
// "elephant goes toot"
sayings.clear();
sayings.size; // 0
Object和Map的比较
一般地,objects会被用于将字符串类型映射到数值。Object允许设置键值对、根据键获取值、删除键、检测某个键是否存在。而Map具有更多的优势。
Object的键均为String类型,在Map里键可以是任意类型。- 必须手动计算
Object的尺寸,但是可以很容易地获取使用Map的尺寸。 Map的遍历遵循元素的插入顺序。Object有原型,所以映射中有一些缺省的键。(可以用map = Object.create(null) 回避)。
这三条提示可以帮你决定用Map还是Object:
- 如果键在运行时才能知道,或者所有的键类型相同,所有的值类型相同,那就使用
Map。 - 如果需要将原始值存储为键,则使用
Map,因为Object将每个键视为字符串,不管它是一个数字值、布尔值还是任何其他原始值。 - 如果需要对个别元素进行操作,使用
Object。
WeakMap对象
WeakMap对象也是键值对的集合。它的键必须是对象类型,值可以是任意类型。它的键被弱保持,也就是说,当其键所指对象没有其他地方引用的时候,它会被 GC 回收掉。WeakMap提供的接口与Map相同。
与Map对象不同的是,WeakMap的键是不可枚举的。不提供列出其键的方法。列表是否存在取决于垃圾回收器的状态,是不可预知的。
可以在"Why WeakMap?"WeakMap查看更多信息和示例。
WeakMap对象的一个用例是存储一个对象的私有数据或隐藏实施细节。Nick Fitzgerald 的博文"Hiding Implementation Details with ECMAScript 6 WeakMaps"提供了一个例子。对象内部的私有数据和方法被存储在WeakMap类型的privates变量中。所有暴露出的原型和情况都是公开的,而其他内容都是外界不可访问的,因为模块并未导出privates对象。
js
const privates = new WeakMap();
function Public() {
const me = {
// Private data goes here
};
privates.set(this, me);
}
Public.prototype.method = function () {
const me = privates.get(this);
// Do stuff with private data in `me`...
};
module.exports = Public;
集合
Set对象
数组和集合的转换
可以使用Array.from或展开操作符来完成集合到数组的转换。同样,Set的构造器接受数组作为参数,可以完成从Array到Set的转换。需要重申的是,Set对象中的值不重复,所以数组转换为集合时,所有重复值将会被删除。
js
Array.from(mySet);
[...mySet2];
mySet2 = new Set([1,2,3,4]);
Array和Set的对比
WeakSet对象
Map的键和Set的值的等值判断
Map的键和Set的值的等值判断都基于same-value-zero algorithm:
- 判断使用与
===相似的规则。 -0和+0相等。NaN与自身相等(与===有所不同)。