ES6(2015)Map
Posted 优小U
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES6(2015)Map相关的知识,希望对你有一定的参考价值。
ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”
的对应,Map 结构提供了“值—值”
的对应,是一种更完善的 Hash 结构实现。如果你需要“键值对”的数据结构,Map 比 Object 更合适。
1. 基本语法
let map = new Map([1,'one'],[2,'two'])
Map中可以是一个数组或者其他 iterable 对象,其元素为键值对。 每个键值对都会添加到新的 Map。null 会被当做 undefined。
添加数据
let keyObj = {}
let keyFunc = function() {}
let keyString = 'a string'
// 添加键
map.set(keyString, "string value")
map.set(keyObj, 'object value')
map.set(keyFunc, 'function value')
删除数据
// 删除指定的数据
map.delete(keyString)
// 删除所有数据
map.clear()
统计数据
// 统计所有 key-value 的总数
console.log(map.size) //2
// 判断是否存在 key-value
console.log(map.has(keyObj)) // true
查询数据
get()
方法返回某个 Map 对象中的一个指定元素
console.log(map.get(keyObj)) // 和键keyObj关联的值
2. 遍历方式
keys()
返回按照顺序插入Map
对象中每个元素的 key 值values()
返回按顺序插入Map
对象中每个元素的 value 值entries()
返回包含[key, value]
对的Iterator
对象,顺序与 Map 对象的插入顺序相同forEach()
按插入顺序对Map
对象进行遍历for...of
可以直接遍历每个成员
for (let key of map.keys()) {
console.log(key)
}
for (let value of map.values()) {
console.log(value)
}
for (let [key, value] of map.entries()) {
console.log(key, value)
}
map.forEach((value, key) => console.log(value, key))
for (let [key, value] of map) {
console.log(key, value)
}
Object
与 Map
的对比:
- 键的类型:
Object
的键只能是字符串或Symbol
类型;Map
可以是任意值(包括函数、对象等) - 键的顺序:
Object
的键值对是无序的;Map
中的键值对是有序的,遍历时是按插入的顺序; - 个数统计:
Object
键值对个数只能手动计算;Map
可以用size
属性获取个数; - 键值对遍历:
Map
迭代方法更多; - 性能:
Map
在频繁增删键值对的场景下性能较好
3. WeekMap
WeakMap
结构与Map
结构类似,也是用于生成键值对的集合。
// WeakMap 可以使用 set 方法添加成员
const wm1 = new WeakMap()
const key = {
foo: 1
}
wm1.set(key, 2)
wm1.get(key) // 2
// WeakMap 也可以接受一个数组,
// 作为构造函数的参数
const k1 = [1, 2, 3]
const k2 = [4, 5, 6]
const wm2 = new WeakMap([
[k1, 'foo'],
[k2, 'bar']
])
wm2.get(k2) // "bar"
WeakMap
与Map
的区别有两点:
- WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名
- WeakMap 不能包含无引用的对象,否则会被自动清除出集合(垃圾回收机制);
const map = new WeakMap()
map.set(1, 2)
// TypeError: 1 is not an object!
map.set(Symbol(), 2)
// TypeError: Invalid value used as weak map key
map.set(null, 2)
// TypeError: Invalid value used as weak map key
WeakMap有什么作用呢?
- 通过 WeakMap 缓存计算结果
// 使用 WeakMap,你可以将先前计算的结果与对象相关联,而不必担心内存管理。以下功能 countOwnKeys() 是一个示例:它将以前的结果缓存在 WeakMap 中 cache。
const cache = new WeakMap();
function countOwnKeys(obj) {
if (cache.has(obj)) {
return [cache.get(obj), 'cached'];
} else {
const count = Object.keys(obj).length;
cache.set(obj, count);
return [count, 'computed'];
}
}
let obj = { name: "kakuqo", age: 30 };
console.log(countOwnKeys(obj));
// [2, 'computed']
console.log(countOwnKeys(obj));
// [2, 'cached']
obj = null; // 当对象不在使用时,设置为null
- 在 WeakMap 中保留私有数据
// 在以下代码中,WeakMap _counter 和 _action 用于存储以下实例的虚拟属性的值:
const _counter = new WeakMap();
const _action = new WeakMap();
class Countdown {
constructor(counter, action) {
_counter.set(this, counter);
_action.set(this, action);
}
dec() {
let counter = _counter.get(this);
counter--;
_counter.set(this, counter);
if (counter === 0) {
_action.get(this)();
}
}
}
let invoked = false;
const countDown = new Countdown(3, () => invoked = true);
countDown.dec();
countDown.dec();
countDown.dec();
console.log(`invoked status: ${invoked}`)
以上是关于ES6(2015)Map的主要内容,如果未能解决你的问题,请参考以下文章
商城项目05_ES6 - varlet const解析表达式模板字符串箭头函数map reduceObject优化