【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}`)
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

优小U

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值