正在加载...

Map 与 Set

Map 把饮料记在客人名下。Set 收配料,每种只留一次。lida 起初是 tea,随后换成 mint。mint 和 lemon 进集合。页面上的一行是 lida / mint / 2。

严格模式那一页是另一回事

那里因为名字没声明而抛出 ReferenceError。这一页什么都不抛。键不存在时,get 给出 undefined。

同一个键,饮料被换掉

orders.set("lida", "tea") 记下第一杯。orders.set("lida", "mint") 不会多出一行,而是盖掉这个键上的值。size 数的是键,不是 set 被调用了几次。

换掉一杯饮料

javascript
const orders = new Map();
orders.set("lida", "tea");
orders.set("lida", "mint");
console.log(orders.get("lida"));
console.log(orders.size);

日志先是 mint,接着是 1。nima 从未存过,所以 orders.get("nima") 为 undefined。orders.has("lida") 为 true。读 Map 用 get。orders.lida 和 orders["lida"] 是普通对象的写法,读不到这张 Map。

键就是那个对象

Map 可以用对象当键。留下的是对象本身,不是由字段拼出的字符串。字段相同的另一个对象仍是另一个键。

对象键各自独立

javascript
const cup = { guest: "lida" };
const other = { guest: "lida" };
const orders = new Map();
orders.set(cup, "tea");
console.log(orders.get(cup));
console.log(orders.get(other));
console.log(orders.size);

日志依次是 tea、undefined、1。普通对象会把两个键都变成字符串 "[object Object]",于是第二次写入会盖掉第一次。Map 不会这样。

第二次 mint 不会留下

add("mint") 调用两次,仍然只有一份 mint。lemon 是另一个值,所以 size 为 2。has 只回答有或没有,不把值交出来。

配料不重复

javascript
const extras = new Set();
extras.add("mint");
extras.add("mint");
extras.add("lemon");
console.log(extras.size);
console.log(extras.has("lemon"));

日志是 2,然后是 true。new Set(["mint", "mint", "lemon"]) 得到同一个集合:多出来的 mint 已经去掉。Set 里只有值,不会把饮料记在某个客人名下。

delete 删掉一条

删掉了东西,delete 返回 true。值本来没有,就返回 false,集合保持原样。

去掉 lemon

javascript
const extras = new Set(["mint", "lemon"]);
console.log(extras.delete("lemon"));
console.log(extras.size);
console.log(extras.has("lemon"));

日志是 true,然后 1,然后 false。mint 还在。Map 也有 delete 和 has,不过它们按键来:orders.delete("lida") 去掉这位客人。

页面写出的那一行

页面换掉 lida 的饮料,用三个词建成集合,再写出客人、饮料和 size。

页面上的那一行

html
<!DOCTYPE html>
<html>
<body>
<p id="line">…</p>
<script>
const orders = new Map();
orders.set("lida", "tea");
orders.set("lida", "mint");
const extras = new Set(["mint", "mint", "lemon"]);
const line = document.querySelector("#line");
line.textContent = "lida / " + orders.get("lida") + " / " + extras.size;
</script>
</body>
</html>

读出来是 lida / mint / 2。第一次 set 成 tea 已经看不见。重复的 mint 不会把 size 抬高。ReferenceError 属于严格模式那一行。

柜台前五步

  1. 先把 lida 设成 tea,再设成 mint。get("lida") 是 mint,size 是 1。
  2. 把 tea 存在 cup 下面。get(other) 是 undefined,size 仍是 1。
  3. 加入 mint、再加入 mint、再加入 lemon。size 是 2,has("lemon") 是 true。
  4. 删掉 lemon。size 是 1,has("lemon") 是 false。
  5. 看页面。这一行是 lida / mint / 2。

容易走错的地方,以及要记住的

同一个键上的第二次 set 是更新。同一个配料的第二次 add 会被忽略。

  • 不要用 orders["lida"] 去读这张 Map
  • 两个长得像的对象不是同一个键
  • has 不返回饮料
  • new Set 一开始就丢掉重复
  • 不要把这一行读成 ReferenceError

记住

  • set 会替换,size 保持不变
  • 对象键就是对象本身
  • Set 每个值只留一次
  • delete 删掉一条
  • 页面这一行是 lida / mint / 2

🧠 测试您的知识

准备开始

测试您的知识

通过这个互动测验挑战自己,看看你对这个主题的理解程度如何

❓
4
问题
🎯
70%
及格要求
♾️
∞
时间
🔄
∞
尝试次数

📝 说明

  • 仔细阅读每个问题
  • 为每个问题选择最佳答案
  • 您可以随时重新参加测验
  • 您的进度将显示在顶部