javascript 高级编程系列 - Set集合与Map集合
ES6中新增的Set集合类型是一种有序列表,其中含有一些相互独立的非重复值,通过Set集合可以快速访问其中
的数据,更有效地追踪各种离散值。
1. 创建Set集合并添加元素
调用new Set()创建Set集合,调用add()方法向集合中添加元素,访问集合的size属性可以获取集合中目前的
元素数量。
let set = new Set();
set.add(5);
set.add('5');
console.log(set.size); // 2
向Set集合中添加多个对象,则它们之间彼此保持独立
let set = new Set();
const k1 = {};
const k2 = {};
set.add(k1);
set.add(k2);
console.log(set.size); // 2
Set集合具有去重功能
let set = new Set([1, 2, 3, 4, 5, 5, 5]);
console.log(set.size); // 5
console.log([...set]); // [1, 2, 3, 4, 5]
Set构造函数可接受所有可迭代对象作为参数(数组,Set集合,Map集合)
let set1 = new Set([1, 2, 3]);
let set2 = new Set(set1);
let map = new Map([['name', 'leon'], ['age', 30]]);
let set3 = new Set(map);
console.log(set2.size); // 3
console.log([...set2]); // 1, 2, 3
console.log(set3.size); // 2
console.log([...set3]); // [['name', 'leon'], ['age', 30]]
2. has()方法检测Set集合中是否存在某个值
let set = new Set();
set.add(5);
set.add('5');
console.log(set.has(5));
console.log(set.has(6));
3. 移除元素
delete()方法可以移除Set集合中的某一个元素,clear()方法会移除集合中的所有元素。
let set = new Set();
set.add(5);
set.add('5');
console.log(set.has(5)); // true
set.delete(5); // 删除元素
console.log(set.has(5)); // false
console.log(set.size); // 1
set.clear();
console.log(set.has('5')); //false
console.log(set.size); // 0
4. forEach遍历Set集合
forEach接受三个参数:
- Set集合中下一次索引的位置数据
- 与第一个参数一样的值
- 被遍历的Set集合本身
let set = new Set([3, 2]);
set.forEach(function(value, key, ownerSet){
console.log(key + ':' + value);
console.log(ownerSet === set);
});
5. 将Set集合转换为数组
let set = new Set([1, 2, 3, 3, 4, 5]);
let array = [...set];
console.log(array); // [1, 2, 3, 4, 5]
6. Weak Set 集合
Weak Set 集合只存储对象的弱引用,并且不可以存储原始值;集合中的弱引用如果是对象唯一的引用,
则会被回收并释放相应内存。
Weak Set 集合只支持三个方法:add(), has(), delete()
let set = new WeakSet();
let key = {};
set.add(key);
console.log(set.has(key)); // true
set.delete(key);
console.log(set.has(key)); // false
WeakSet集合只能保存对象的弱引用
let set = new WeakSet();
let key = {};
set.add(key);
console.log(set.has(key)); // true;
key = null; // 移除对象key的最后一个强引用(Weak Set中的引用也自动移除)
7. 创建Map集合
ES6中的Map集合是一种存储着许多键值对的有序列表,其中的键名和对应的值支持所有的数据类型。
Map集合使用set(key, value)方法添加元素,get(key) 获取信息
let map = new Map();
map.set('title', 'ECMAScript 6');
map.set('year', 2023);
console.log(map.get('title')); // ECMAScript 6
console.log(map.get('year')); // 2023
8. Map 集合支持的方法
- has(key) 检测指定的键名在Map集合中是否已经存在
- delete(key) 从Map集合中移除指定键名及其对应的值
- clear() 移除Map集合中的所有键值对
- size 属性表示当前集合中键值对的数量
let map = new Map();
map.set('name', 'Nicholas');
map.set('age', 25);
console.log(map.size); // 2
console.log(map.has('name')); // true
console.log(map.get('name')); // Nicholas
map.delete('name');
console.log(map.has('name')); // false
console.log(map.get('name')); // undefined
console.log(map.size); // 1
map.clear();
console.log(map.has('age')); // false
console.log(map.get('age')); // undefined
console.log(map.size); // 0
9. 初始化Map集合
let map = new Map([['name', 'Nicholas'], ['age', 25]]);
console.log(map.has('name')); // ture
console.log(map.get('name')); // 'Nicholas'
console.log(map.size); // 2
10. 遍历Map集合
使用forEach方法
let map = new Map([['name', 'Nicholas'], ['age', 25]]);
map.forEach(function(value, key, ownerMap){
console.log(key + ':' + value);
console.log(ownerMap === map);
});
使用for-of循环
let map = new Map([['name', 'Nicholas'], ['age', 25]]);
for (let [key, value] of map){
console.log(key + ':' + value);
}
11. 使用Weak Map集合
ES6中的Weak Map类型是一种存储着许多键值对的无序列表,列表的键名必须是非null类型的对象,键名对应
的值则可以是任意类型。
let map = new WeakMap();
element = document.querySelector('.element');
map.set(element, 'Original');
let value = map.get(element);
console.log(value); // 'Original'
// 移除element元素
element.parentNode.removeChild(element);
element = null;
- Weak Map 支持的方法
has(), delete()
let map = new WeakMap();
element = document.querySelector('.element');
map.set(element, 'Original');
console.log(map.has(element)); // true
console.log(map.get(element)); // "Original"
map.delete(element);
console.log(map.has(element)); // false
console.log(map.get(element)); // undefined
- 利用Weak Map创建私有对象
let Person = (function(){
let privateData = new WeakMap();
function Person(name){
privateData.set(this, {name: name});
}
Person.prototype.getName = function() {
return privateData.get(this).name;
}
return Person;
}());