Skip to content

map 集合用于存储多个键值对数据,键值对数据也可以用对象来存储:

对象存储键值对的特点

  1. 键名只能是字符串或 Symbol
  2. 无法方便地获取数据的数量
  3. 存在原型链,可能导致冲突,从而污染原型链

而 map 正好解决了这些问题,接下来介绍 map 的使用

js
const m = new Map();//创建一个空map

const m2 = new Map(iterable);//可以传入一个可迭代对象,根据可迭代对象的迭代结果创建一个map,注意,这个迭代结果有具体要求,每次迭代的结果必须是长度为2的数组,数组的第一项为key,第二项为value。

const m3 = new Map([["a",3],["b",4]]);//这样就可以正确创建一个map,第一项为"a"=>3,第二项为"b"=>4

m3.size;//可以获取到当前map中键的数量,只读属性

m3.set(键,值);//设置一个键值对,注意,这里的键和值可以是任何类型的数据

//在map中键是不能重复的,如果使用set,键不存在,则添加一项,如果键存在,则修改

//map比较键的方式和set相同

m3.get(键);//根据一个键,得到对应的值,如果传入一个不存在的键,返回undefined

m3.has(键);//用于判断某个键是否存在,返回布尔值

m3.delete(键);//用于删除指定的键,返回是否删除成功

m3.clear();//清空map

//我们可以使用展开运算符将map转换为数组
[...m3];//可以转换为数组,数组的每一项为一个长度为2的数组,分别记录了键和值

//由于map也是可迭代的,所以使用for...of循环可以进行遍历,每次得到的是长度为2的数组,除此之外,使用forEach方法也可以遍历,方法同Set类似,每次回调函数传入的也是长度为2的数组。
for(const item of m3){
	console.log(item);
}
for(const [key,value] of m3){
	console.log(key,value);//可以进行解构,更方便
}
m3.forEach(item => {
	console.log(item);
});

手写 Map:

js
/**
 * MyMap类实现了基本的键值对映射功能。
 * @constructor
 * @param {Iterator} iterator - 迭代器,用于初始化MyMap实例的键值对。
 */
class MyMap {
	constructor(iterator) {
		this._data = []; // 存储键值对的内部数组
		if (!iterator) {
			return;
		}
		// 遍历迭代器,验证并初始化键值对
		for (const item of iterator) {
			if (!Array.isArray(item) || item.length !== 2) {
				throw "你这个迭代器不对";
			}
			this.set(item[0], item[1]);
		}
	}

	/**
	 * 实现可迭代协议,使MyMap实例可以被遍历。
	 * @yields {Array} - 逐个yield存储的键值对。
	 */
	*[Symbol.iterator]() {
		this._data.forEach(item => {
			yield item;
		});
	}

	/**
	 * 获取MyMap实例中存储的键值对数量。
	 * @returns {number} - 存储的键值对数量。
	 */
	get size() {
		return this._data.length;
	}

	/**
	 * 添加或更新键值对。
	 * @param {any} key - 键。
	 * @param {any} value - 值。
	 */
	set(key, value) {
		if (!this.has(key)) {
			this._data.push([key, value]); // 如果键不存在,则添加新的键值对
		} else {
			this._data.map(item => {
				if (item[0] === key) {
					item[1] = value; // 如果键存在,则更新对应的值
				}
			});
		}
	}

	/**
	 * 检查指定键是否存在于MyMap实例中。
	 * @param {any} key - 要检查的键。
	 * @returns {boolean} - 键存在返回true,否则返回false。
	 */
	has(key) {
		for (const item of this_data) {
			if (item[0] === key) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 获取指定键对应的值。
	 * @param {any} key - 要获取值的键。
	 * @returns {any} - 返回键对应的值,如果不存在返回undefined。
	 */
	get(key) {
		for (const item of this_data) {
			if (item[0] === key)
				return item[1];
		}
	}

	/**
	 * 清除MyMap实例中所有的键值对。
	 */
	clear() {
		this._data = [];
	}

	/**
	 * 对MyMap实例中的所有键值对执行给定的回调函数。
	 * @param {Function} fn - 回调函数,接受三个参数:当前键值对,MyMap实例。
	 */
	forEach(fn) {
		for (const item of this_data) {
			fn(item, item, this);
		}
	}
}

以笔记为镜,可以知得失