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)
}

ObjectMap 的对比:

  • 键的类型: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"

WeakMapMap的区别有两点:

  • 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的主要内容,如果未能解决你的问题,请参考以下文章

你如何 JSON.stringify ES6 Map?

商城项目05_ES6 - varlet const解析表达式模板字符串箭头函数map reduceObject优化

商城项目05_ES6 - varlet const解析表达式模板字符串箭头函数map reduceObject优化

ES6 模块串联

是否可以对 ES6 地图对象进行排序?

ES6新特性:map和reduce