视频加载失败

ES6Set和Map数据结构

1922 字
10 分钟
ES6Set和Map数据结构

Set是什么#

Set 是 ES6 引入的一种集合(Collection)类型,特点是存储唯一值,不允许重复元素。有点像数组,但会自动去重。

Set没有下标去标示每一个值,所以Set是无序的,也不能像数组那样通过下标去访问Set的成员

const set = new Set();
set.add(1);
set.add(2);
set.add(2);
console.log(set);//Set(2) { 1, 2 }

Set实例的方法和属性#

常用方法

add() 添加元素

const set = new Set();
set.add('Tom').add('Alex');
set.add('Jerry');
console.log(set);

delete() 删除元素

set.delete('Tom');
console.log(set);

has()判断是否存在

const set = new Set([1, 2, 3]);
console.log(set.has(2)); // true
console.log(set.has(4)); // false

clear()清空集合

set.clear();
console.log(set.size); // 0

size获取元素个数

const set = new Set([1, 2, 3]);
console.log(set.size); // 3
//类似数组的:arr.length

遍历 Set获取元素值

for…of

const set = new Set([1, 2, 3]);
for (const item of set) {
console.log(item);
}

forEach

set.forEach(item => {
console.log(item);
});
//this指向谁,取决于外部环境,this 指向的是 外层作用域的 this

forEach的this指向问题

以下代码中:this指向谁:

const set = new Set();
set.add('Tom').add('Alex');
set.add('Jerry');
set.forEach((item) => {
console.log(item);
});
//对象
const obj = {
name: 'A',
run() {
set.forEach((item) => {
console.log(this.name);
});
}
};
//class
class A {
run() {
set.forEach((item) => {
console.log(this);
});
}
}
//普通函数
set.forEach(function(item) {
console.log(this);
});
//普通函数,forEach第二个参数指定this
set.forEach(function(item) {
console.log(this);
}, obj);
  • 在浏览器普通脚本中:this === window(非严格模式)或 undefined(严格模式)
  • 在对象方法中:这里 this === obj
  • 在 class 中:this === 当前 class 实例
  • 换成普通函数:默认:undefined(严格模式),或 window(非严格模式)或可以通过 forEach 第二个参数 指定

Set 与 Array 对比

特性ArraySet
允许重复✅❌
按索引访问✅❌
自动去重❌✅
长度lengthsize
查找元素includes()has()

Set构造函数的参数#

Set 构造函数的参数是一个可迭代对象(iterable),用来初始化集合中的元素。

可以是任何可迭代对象,比如:Array(数组)、String(字符串)、Map(会取 key-value 中的 key)、Set、arguments、任何实现了 Symbol.iterator 的对象,如果不传参数,默认创建一个空 Set。

//数组
const s = new Set([1, 2, 3]);
console.log(s); // Set(3) {1, 2, 3}
//自动去重(核心特性)
const s = new Set([1, 1, 2, 2, 3]);
console.log(s); // Set(3) {1, 2, 3}
//字符串(按字符拆分)
const s = new Set("hello");
console.log(s); // Set(4) {'h','e','l','o'}
//Map(只取 key)
const m = new Map([
["a", 1],
["b", 2]
]);
//Map(只取 key)
const s = new Set(m);
console.log(s); // Set(2) {'a', 'b'}
//不传参数
const s = new Set();
console.log(s); // Set(0) {}

Set 的注意事项#

如何判断重复值

//注意点:Set 判断元素是否重复使用的是 SameValueZero(类似 ===,但 NaN 也相等)
//对象引用不同即使内容一样也不会去重:
const obj = new Set([{a:1}, {a:1}]) // 仍然是两个元素
console.log(obj); // Set(2) { { a: 1 }, { a: 1 } }

什么时候用Set

//数组或者字符串去重的时候
//不需要通过下标访问,只需要遍历时
//为了使用Set提供的方法和属性时(add delete clear has forEach size 等)

Set的应用#

黑名单:

const blacklist = new Set([
'Tom',
'Jerry'
]);
if (blacklist.has(username)) {
// 禁止访问
}

展开set

const s = new Set([1,2,3])
console.log([...s]);

字符串去重

const s = new Set(‘abbaerfghh’)
console.log([...s].join(''));//去重之后,重新展开,重新转为字符串 数组的join()方法可以使数组转为字符串

存放DOM元素

const selected = new Set(document.querySelectorAll("p"));
selected.forEach(el => {
el.style.color = "red";
});

Map是什么#

Map 是 JavaScript 中的一种键值对集合结构,和普通对象 {} 类似,但功能更强、更规范。

const map = new Map();
map.set('name', 'Alice');
map.set('age', 18);
console.log(map.get('name')); // Alice

Map 和 Object 的核心区别

key 的类型更自由(Map 更强)

//Object key 只能是 字符串 / Symbol
const obj = {};
obj[1] = "a";
obj[true] = "b";
console.log(obj); // key 会被转成字符串
//Map key 可以是任何类型
const map = new Map();
map.set(1, "数字key");
map.set(true, "布尔key");
map.set({}, "对象key");
console.log(map.get(1)); // 数字key

Map 保持插入顺序

const map = new Map();
map.set("a", 1);
map.set("b", 2);
map.set("c", 3);
for (const [k, v] of map) {
console.log(k, v);
}

Map 自带 size

const map = new Map();
map.set("a", 1);
map.set("b", 2);
console.log(map.size); // 2

Map 实例的属性和方法#

常用方法

set(添加/修改)

map.set("name", "Tom");

get(获取)

map.get("name");

delete() 删除

map.delete("name");

has()判断是否存在

map.has("name"); // true

clear()清空

map.clear();

size获取个数

map.size();

遍历Map获取元素值

for…of

for (const [key, value] of map) {
console.log(key, value);
}

forEach(callback)

const map = new Map([
["a", 1],
["b", 2]
]);
map.forEach((value, key) => {
console.log(key, value);//注意顺序是:value 在前,key 在后(和 set 不同)
});

keys / values / entries

for (const key of map.keys()) {
console.log(key);
}
for (const value of map.values()) {
console.log(value);
}
for (const entry of map.entries()) {
console.log(entry);
}
for (const [k, v] of map) {
console.log(k, v);
}
//map.keys();
//map.values();
//map.entries();

Map 构造函数的参数#

Map 构造函数的参数是一个可迭代对象(iterable),用于在创建 Map 时初始化键值对数据。

set、map、键值对数组

//数组,必须是二维结构
const map = new Map([
["name", "Alice"],
["age", 18]
]);
// new Map(["a", "b"]);//❌ 错误用法
console.log(map.get("name")); // Alice
//由 Map 构造 Map(复制)相当于浅拷贝(key/value 引用不变)
const m1 = new Map([
["a", 1],
["b", 2]
]);
const m2 = new Map(m1);
console.log(m2.get("a")); // 1
//Set ❌ 不能直接用(容易踩坑)
new Map(new Set([1, 2, 3]));//❌ 错误用法

Map 的注意事项#

key 不会自动转换类型

const map = new Map();
map.set(1, "number");
map.set("1", "string");
console.log(map.size); // 2,在 Object 里 "1" 和 1 可能会混在一起,但 Map 不会

NaN 是相等的(特殊规则)

const map = new Map();
map.set(NaN, 1);
map.set(NaN, 2);
console.log(map.size); // 1
console.log(map.get(NaN)); // 2

对象 key 比较的是“引用”

const map = new Map();
map.set({}, 1);
map.set({}, 2);
console.log(map.size); // 2

delete 返回值很重要

map.delete("a"); // true / false用来判断是否真的删除成功

Map 不会自动去重 value

map.set("a", 1);
map.set("b", 1);
console.log(map.size); // 2去重只针对 key,不针对 value

如何判断键名是否相同:Map 的 key 判断遵循 ===

//基本类型(字符串/数字/布尔)相同 key(直接覆盖)
map.set("a", 1);
map.set("a", 2);
//NaN 特殊处理 认为相同 key
map.set(NaN, 1);
map.set(NaN, 2);
//对象,引用比较,不相同(不同引用)
map.set({a:1}, 1);
map.set({a:1}, 2);
//同一个对象才算同一个 key
const obj = {a:1};
map.set(obj, 1);
map.set(obj, 2);
console.log(map.size); // 1

什么时候用Map

//key 不是字符串时(必须用 Map)Object 做不到(会变成 "[object Object]")
const map = new Map();
const el = document.querySelector("div");
map.set(el, { clicked: true });
//频繁增删数据;Map 比 Object 更稳定,不会触发 hidden class 变化
map.set("a", 1);
map.delete("a");
//需要有序数据结构;遍历顺序 = 插入顺序
map.set("a", 1);
map.set("b", 2);
map.set("c", 3);
//需要快速查找 + 动态变化
//缓存
const cache = new Map();
function getData(key) {
if (cache.has(key)) return cache.get(key);
const result = key * 2;
cache.set(key, result);
return result;
}
//DOM 状态管理
const selected = new Map();
selected.set(dom, true);
//需要避免 Object 原型污染Map 没有这个问题
const obj = {};
obj.__proto__ = "hack";

什么时候不用 Map

//静态数据(推荐 Object)更简单 + JSON 友好
const user = {
name: "Alice",
age: 18
};
//需要 JSON 序列化:Map 不能直接 stringify
//简单配置数据 Object 更清晰

Map的应用#

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
/* p {
background-color: orange;
font-size: 40px;
} */
</style>
</head>
<body>
<p>1</p>
<p>2</p>
<p>3</p>
<script>
const p = document.querySelectorAll('p');
// console.log(p);
//解构
const [p1, p2, p3] = document.querySelectorAll('p');
const m = new Map([
[p1, { color: 'red', backgroundColor: 'pink', fontSize: '40px' }],
[p2, { color: 'blue', backgroundColor: 'orange', fontSize: '40px' }],
[p3, { color: 'yellow', backgroundColor: 'green', fontSize: '40px' }],
]);
m.forEach((propObject, elem) => {
//console.log(propObject);
for (const p in propObject) {
// console.log(propObject);
// console.log(p);
// console.log(propObject[p]);
elem.style[p] = propObject[p];
//elem.style.p = propObject[p]; 错误,这是静态调用
}
});
</script>
</body>
</html>

把对象改为Map:

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
/* p {
background-color: orange;
font-size: 40px;
} */
</style>
</head>
<body>
<p>1</p>
<p>2</p>
<p>3</p>
<script>
const p = document.querySelectorAll('p');
// console.log(p);
//解构
const [p1, p2, p3] = document.querySelectorAll('p');
const m = new Map([
[
p1,
new Map([
['color', 'red'],
['backgroundColor', 'pink'],
['fontSize', '40px'],
]),
],
[
p2,
new Map([
['color', 'blue'],
['backgroundColor', 'orange'],
['fontSize', '40px'],
]),
],
[
p3,
new Map([
['color', 'yellow'],
['backgroundColor', 'green'],
['fontSize', '40px'],
]),
],
]);
m.forEach((styleMap, elem) => {
styleMap.forEach((value, key) => {
elem.style[key] = value;
});
});
</script>
</body>
</html>

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

ES6Set和Map数据结构
https://f.youzi177.cn/posts/2026102108es6set-he-map-shu-ju-jie-gou/
作者
小封鸭
发布于
2026-10-21
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
小封鸭
小楼一夜听春雨,深巷明朝卖杏花
公告
欢迎来到我的博客。这里主要记录前端全栈和日常内容
分类
标签
最新动态
站点统计
文章
60
分类
3
标签
12
总字数
107,734
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
EdgeOne Pages
博客版本
Firefly v6.16.8
文章许可
CC BY-NC-SA 4.0
文章目录