map 集合用于存储多个键值对数据,键值对数据也可以用对象来存储:
对象存储键值对的特点
- 键名只能是字符串或 Symbol
- 无法方便地获取数据的数量
- 存在原型链,可能导致冲突,从而污染原型链
而 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);
}
}
}