javascript 高级编程系列 - Set集合与Map集合

发布时间 2023-03-24 14:07:45作者: 箫笛

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;
}());