笔记:《JavaScript学习指南》-第10章maps和sets

第10章 maps 和 sets

ES6引入的数据结构:maps 和sets。

10.1 maps

Map 是将键和值映射起来的绝佳选择。
例如:把 user 对象映射到 role
const u1 = {name:"liang"};
const u2 = {name:"zhu"};
const u3 = {name:"ping"};
const u4 = {name:"zhang"};

//创建 Map 对象
const userRoles = new Map();

//使用map 中的 set() 方法把user 赋给 role,可链式调用
userRoles
    .set(u1,"user")
    .set(u2,"user")
    .set(u3,"Admin")
在上例中,创建 Map 对象时,可以传入一个包含了数组的数组:
//...创建对象u1,u2,u3,u4...

//创建 Map 的构造函数传入数组
const userRoles = new Map([
    [u1,"user"],
       [u2,"user"],
       [u3,"Admin"]
]);

//然后可以使用 get() 方法,就可以知道u2 有什么 role
userRoles.get(u2);    //"user"

//使用 has() 方法来查看 map 中是否含有给定的 key
userRoles.has(u2);    //true
userRoles.has(u4);    //false
//如果 u4 未定义则为undefined

//使用 set() 方法重新设置映射
userRoles.set(u2,"Admin");

// size 属性返回map中的元素个数
userRoles.size;    //3


keys() 方法可以取得map 中所有的键。
values() 方法可以取得所有的值。
entries() 方法以数组的方式获取键值对。
所有这些方法都返回一个可以迭代的对象,从而能用for...of 循环来迭代:
//...创建map对象...

for(let u of userRoles.keys())
    console.log(u.name);    //liang  zhu  ping

for(let r of userRoles.values())
    console.log(r);    //user  admin

for(let ur of userRoles.entries())
    console.log(`${ur[0].name}: ${ur[1]}`);    //liang:user zhu:user ping:Admin

//通过解构让迭代更自然
for(let [u,r] of userRoles.entries())
    console.log(`${u.name}: ${r}`);

//entries() 方法是Map的默认迭代器,所以上例可以简化为:
for(let [u,r] of userRoles)
    console.log(`${u.name}: ${r}`);

// delete() 方法可以删除map 中的一个条目
userRoles.delete(u2);

//clear() 方法删除map 中所有条目
userRoles.clear();

10.2 Weak maps

WeakMap 跟Map 在本质上是相同的,除了以下几点:
  • key 必须是对象
  • WeakMap 中的 key 可以被垃圾回收
  • WeakMap 不能迭代或者清空
相比maps,它可以使用的方法有set, get, has, delete。不能使用clear, keys, values, entries.

可以用来存储对象实例中的私有key。
const SecretHolder = (function(){
    const secrets = new WeakMap();
    return class {    //这里的class 让Secretholder 成为一个类
        setSecret(secret){
            secrets.set(this, secret);
        }

        getSecret(){
            return secrets.get(this);
        }
    }
})();
把WeakMap 放在IIFE 中,同时还放入了一个使用它的类。IIFE 外,类 SecretHolder 的实例可以存储 secrets。这样一来,secret 的赋值和取值只能分别通过 getSecret 方法和 getSecret 方法来完成:
//...接上例...

const a = new SecretHolder();
const b = new SecretHolder();

a.setSecret("secret A");
b.setSecret("secret B");

a.getSecret();    //"secret A"
b.getSecret();    //"secret B"
这里也可以用普通的Map,但这样会导致该实例中的secret 永远不会被垃圾回收。

10.3 sets

sets 是一个不允许重复数据的集合。
相比maps,sets没有set 和get 方法,但是有add 方法。
const roles = new Set();

// add() 方法
roles.add("User");    //Set(1)["User"]

//如果想把这个user 变成管理员
roles.add("Admin");    //Set(2)["User","Admin"]

//不允许重复数据
roles.add("User");    //Set(2) {"User", "Admin"}


roles.has("User");    //true
roles.size;    //2

roles.keys();    //SetIterator {"User", "Admin"}
roles.values();    //SetIterator {"User", "Admin"}
roles.entries();    //SetIterator {"User", "Admin"}

roles.delete("Admin");
roles.size;    //1

roles.clear();
roles.size;    //0
不需要在添加元素的时候检查set 中是否已经有这个元素。

10.4 Weak Sets

Weak Sets 只能包含对象,这些对象可能会被垃圾回收。
和Weak map 类似,weak set 中的值不能被迭代。
它的唯一用处是判断给定对象是不是一个 set。
例子,圣诞老人给调皮的孩子送煤块:
const naughty = new WeakSet();

const children = [
    {name:"liang"},
    {name:"zhu"},
];

naughty.add(children[1]);

for(let child of children){
    if(naughty.has(child))
        console.log(`Coal for ${child.name}!`};
    else
        console.log(`Presents for ${child.name}!`);
}
    //Presents for liang!
        //Coal for zhu!

展开阅读全文

没有更多推荐了,返回首页