ES6 中的 Set 和 Map

本文探讨了在 JavaScript 中为何需要引入 ES6 的 Set 和 Map 数据结构,而非仅依赖对象。文章指出使用对象模拟集合存在的问题,如数值 key 转字符串、无法使用对象作为属性名及布尔值属性自动转换。接着,详细介绍了 Set 的特点,如存储非重复值,以及 WeakSet 的概念,其允许弱引用并节省内存。最后,概述了 Map 的功能,强调它支持任意类型的键值对,并对比了 WeakMap 的特性。

前言

大家心里是否产生过这样的疑问:JS 中既然已经有对象这种数据结构,我们为什么还要再单独去使用 Set 或者 Map 呢?
今天我们来梳理一下其中的缘由,从出现的原因开始学习 Set 和 Map。

使用对象模拟集合的弊端

在 Set 和 Map 的标准出现,大家都会使用对象来模拟集合,比如:

var testObj = Object.create(null);
testObj.foo = 'bar';
if(testObj.foo) {
    // 执行的一些代码
}

但这样的模拟方式,在某些时刻会产生一些如下的不可避免的问题。

数值类型的 key 会被自动转换为字符串

var testObj = Object.create(null);
testObj[1]= 'foo';

console.log(testObj['1']);  // foo

无法用对象作为属性名

var obj1 = {};
var obj2 = {};
var testObj = Object.create(null);

testObj[obj1] = 'foo';
console.log(testObj[obj2]);  // foo

原本我们期望使用不同的对象,作为不同的属性名,但是对象在这种情况下会被自动转换为字符串"[object Object]",所以两个原本不同的对象,指向了一个相同的属性。

属性值为布尔值时会自动转换为 true 或 false

本身这种逻辑是没有问题的,但若我们只是想要判断属性的有无,就会对我们的判断结果造成影响。

var testObj = Object.create(null);
testObj.count = 0;
if(testObj.count) {
    console.log('hello')
}
// 什么都不会打印

综上,我们有了新的 Set 和 Map 标准,来更好应对不同的集合情况。

Set

Set 类型是一种有序的列表,包含相互独立的非重复值。

let set = new Set();

set.add(5);
set.add('5');

使用 add() 方法向集合中添加元素。字符串 5 不会被自动转换为数字类型。

  • 如果相同的 key 添加第二次,那么后来的添加会被忽略。
  • 用数组来初始化 Set 的时候,Set 的构造函数会过滤掉重复的值,保证集合中各元素的唯一。
set.delete(5);  // 移除集合中的某一元素
set.clear();	// 移除集合中的所有元素
set.forEach();  // 三个参数:值、键名、集合本身
set.has(6);		// 判断集合中是否有某个参数,返回 true 或 false

let set = new Set([4, 6, 8, 9, 2]);  // 将数组转换为集合,自动排序去重
let arr = [...set];  				 // 将集合转换为数组

Weak Set

将对象存储在 Set 的实例与存储在 变量中一样,只要 Set 中的引用存在,垃圾回收机制就不能释放对应的内存。
Weak Set 只存储对象的弱引用,且不能存储原始值。当 Weak set 是对象的唯一引用时,就会被垃圾回收机制释放掉内存。

  • Weak Set 不可迭代。
  • Weak Set 不支持 forEach() 方法。
  • Weak Set 不支持 size 属性。

Map

Map 类型是一种存储许多键值对的有序列表。键名和值支持所有数据类型。

let map = new Map();
map.set("hello", "world");
map.get("hello");		// 获取值
map.has(1);				// 判断是否存在某个属性
map.delete("hello");	// 删除某个属性
map.clear(); 			// 移除所有键值对

Map 的 forEach() 与 Set 相似。
WeakMap 也可以直接参考 WeakSet。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值