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 被调用了几次。
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 可以用对象当键。留下的是对象本身,不是由字段拼出的字符串。字段相同的另一个对象仍是另一个键。
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 只回答有或没有,不把值交出来。
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,集合保持原样。
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。
<!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 属于严格模式那一行。
柜台前五步
- 先把 lida 设成 tea,再设成 mint。get("lida") 是 mint,size 是 1。
- 把 tea 存在 cup 下面。get(other) 是 undefined,size 仍是 1。
- 加入 mint、再加入 mint、再加入 lemon。size 是 2,has("lemon") 是 true。
- 删掉 lemon。size 是 1,has("lemon") 是 false。
- 看页面。这一行是 lida / mint / 2。
容易走错的地方,以及要记住的
同一个键上的第二次 set 是更新。同一个配料的第二次 add 会被忽略。
- 不要用 orders["lida"] 去读这张 Map
- 两个长得像的对象不是同一个键
- has 不返回饮料
- new Set 一开始就丢掉重复
- 不要把这一行读成 ReferenceError
记住
- set 会替换,size 保持不变
- 对象键就是对象本身
- Set 每个值只留一次
- delete 删掉一条
- 页面这一行是 lida / mint / 2
🧠 测试您的知识
测试您的知识
通过这个互动测验挑战自己,看看你对这个主题的理解程度如何
📝 说明
- 仔细阅读每个问题
- 为每个问题选择最佳答案
- 您可以随时重新参加测验
- 您的进度将显示在顶部