05-Set与Map
集合 Set
新建集合 - 传入可迭代对象
js
const orderSet = new Set(['pasta', 'pizza', 'pizza', 'risotto', 'pasta']);
console.log(orderSet); // {'pasta', 'pizza', 'risotto'}
Set()
中要传入一个可迭代对象:数组、字符串、集合、Map
size
获得集合中元素的个数
js
console.log(orderSet.size);
has()
检查集合中是否有某个元素
js
console.log(orderSet.has('pizza')); //true
add()
向集合中添加元素
js
console.log(orderSet.add('chicken')); // {'pasta', 'pizza', 'risotto', 'chicken'}
delete()
删除集合中的某个元素
js
console.log(orderSet.delete('chicken')); // true
删除集合中的所有元素: orderSet.clear()
方法
遍历集合
for ... of ...
js
for(const item of orderSet) console.log(item);
forEach()
js
const countries = new Set(['china', 'usa', 'english']);
countries.forEach((value, key, map)=>{
console.log(`${key}: ${value}`); // key 和 value 相同
});
Map
与 Object 非常不同的一点是,Object 的左侧只能是字符串,而 Map 的左侧可以是任意数据类型。
新建 Map (二维数组)与向 Map 中添加元素(set()
)
js
const rest = new Map();
rest.set('name', 'Classico Italiano');
rest.set(1, 'Shen Zhen');
console.log(rest.set(2, 'Guang Zhou')); // {'name' => 'Classico Italiano', 1 => 'Shen Zhen', 2 => 'Guang Zhou'}
rest.set('categories', ['Italian', 'Pizzeria', 'Vegetarian', 'Organic'])
.set('open', 11)
.set('close', 23); // 链式调用
另一种更为常用的创建 Map 的方法:
js
const question = new Map([
['question', 'what is the best language in the world?'],
[1, 'C'],
[2, 'Java'],
[3, 'JavaScript'],
['correct', 3],
[true, 'Correct👍'],
[false, 'Try again!'],
]);
当已有一个对象的时候,将其转为 Map:
js
const openingHours = restaurant.openingHours;
console.log(Object.entries(openingHours));// 二维数组
const hourMap = new Map(Object.entries(openingHours));
console.log(hourMap); //{'thu' => {…}, 'fri' => {…}, 'sat' => {…}}
get()
获取 Map 中的元素
js
console.log(rest.get('name')); // Classico Italiano
has()
检查 Map 中是否有某个元素
js
console.log(rest.has('categories')); // true
delete()
删除 Map 中的某个元素
js
console.log(rest.delete('categories')); // true
size
获取 Map 的大小
js
console.log(rest.size); // 6
Object 作为 key 不能直接 set()
js
console.log(rest.set([1, 2], 'test'));
console.log(rest.get([1, 2])); // undefined
如果想要实现正确的功能,可以像下面这样写:
js
const arr = [3, 4]; // 用变量记住对象的地址
rest.set(arr, 'test2');
console.log(rest.get(arr)); // test2
遍历 Map
for ... of ...
js
for(const [key, value] of question){
if(typeof key === 'number'){
console.log(`Answer are ${key}: ${value}`);
}
}
和对象的迭代很像,唯一的区别是不需要将其转变为可迭代对象。
forEach()
js
const currencies = new Map([
['USD', 'United States dollar'],
['EUR', 'Euro'],
['GBP', 'Pound sterling'],
]);
currencies.forEach((value, key, map)=>{
console.log(`${key}: ${value}`);
});
将 Map 转为 array
js
console.log([...question]); // 转为二维数组
console.log([...question.keys()]); // key 构成的数组
console.log([...question.values()]); // value 构成的数组
WeakMap
根据垃圾回收机制,如果我们使用对象作为 Map
的键,哪怕该对象没有引用指向,该对象也不会被垃圾回收。
而 WeakMap
在这方面有根本上的不同,它不会阻止垃圾回收机制对作为键的对象(key object)的回收。
WeakMap
和 Map
的第一个不同点就是,WeakMap
的键必须是对象,不能是原始值。