ES6学习笔记15:Set和Map

Set

基本用法

Set类似数组,但是它的元素都是唯一的,没有重复值。

构造函数Set()用来生成Set数据结构。

const s = new Set();
[2,3,4,55,55,3].forEach(x => s.add(x));

console.log(Array.from(s)); // [2,3,4,55];

可以通过add()方法为Set结构添加成员.

函数Set()可以接受一个数组或者具有iterable接口的其他数据结构作为参数来初始化

  • 可以利用Set去除数组重复成员
[...new Set(array)];
  • 可以利用Set去除字符串中的重复字符
[...new Set('abababcc')].join(''); // 'abc'

向Set加入值的时候,不会发生类型转换,所以数值5和字符串'5'是两个不同的值。Set内部判断两个值是否不同所使用的算法是“Same-value-zero equality”,“Same-value-zero equality”类似于精确相等运算符(===),两者的区别是 Set 加入值时认为NaN等于自身,而精确相等运算符(===)认为NaN不等于自身。

	  const s = new Set();
    const a = NaN;
    const b = NaN;
    s.add(a);
    s.add(b);
    console.log(a === b);  // false
    console.log(Array.from(s)); // [NaN]

当添加的元素是对象时,在Set内部,对象总是不相等的。

		const s = new Set();
    s.add({});
    s.add({});
    console.log(Array.from(s)); // [{},{}]
    console.log(s.size); // 2

Set实例的属性和方法

属性
  • Set.prototype.constructor:构造函数,默认是Set()
  • Set.prototype.size:返回Set实例的成员总数
操作方法
  • Set.prototype.add(value):添加某个值,返回Set结构本身
  • Set.prototype.delete(value):删除某个值,返回一个布尔值,表示是否删除成功
  • Set.prototype.has(value):返回一个布尔值,表示是否有Set成员
  • Set.prototype.clear():清除所有成员,没有返回值
  • Array.from()可以将Set结构转换为数组
遍历操作
  • Set.prototype.keys():返回键名的遍历器
  • Set.prototype.values():返回键值的遍历器
  • Set.prototype.entries():返回键值对的遍历器
  • Set.prototype.forEach():返回回调函数遍历每个成员

Set结构默认是可遍历的,默认遍历的是values().

WeakSet

基本用法

WeakSet 结构和 Set 类似,也是不重复的值的集合。

WeakSet 与 Set的区别
  • WeakSet成员只能是对象,而不能是其他类型的值。
  • WeakSet中的对象都是弱引用,垃圾回收机制不考虑WeakSet对这个对象的引用。

WeakSet适合临时存放一组对象,以后存放跟对象绑定的信息。

WeakSet实例的属性和方法

WeakSet是一个构造函数,可以使用new命令创建WeakSet数据结构

const ws = new WeakSet();

这里可以接受任何具有Iterable接口的对象作为参数,还需要具有Iterable接口的对象的成员只能是对象。

const ws = new WeakSet([[1, 2], [2, 3]]);
console.log(ws);  // {[1, 2], [2, 3]}
const ws1 = new WeakSet([1, 2]);
console.log(ws1); // ERROR TypeError: Invalid value used in weak set
方法
  • WeakSet.prototype.add(value):向WeakSet实例添加一个新成员
  • WeakSet.prototype.delete(value):清除WeakSet实例的指定成员
  • WeakSet.prototype.has(value):返回一个布尔值,表示WeakSet实例是否有这个值

需要注意:WeakSet没有sizeforEach属性

Map

基本用法

Map数据结构类似于对象(键值对的集合),但是Map的‘键’不限于字符串,各种类型的值(包括对象)都可以当作键。Object提供了‘字符串-值’的对应,Map提供了‘值-值’的对应,是一种更完善的Hash结构实现。

需要注意:
  • 对同一个键多次赋值,后面的值将覆盖前面的值
const map = new Map();
map.set(1,'aaa').set(1,'bbb');
console.log(map.get(1)); // 'bbb'
  • 读取一个未知的键,返回undefined.
console.log(new Map().get('abc')); // undefined
  • 只有同一个对象的引用,Map结构才将其看作同一个键
const map = new Map();
map.set(['a'], 123);
map.get(['a']); // undefined

这里的setget方法,看上去是针对同一个键,但是实际上是两个不同的数组实例,内存地址是不一样的,所有get方法无法读取这个键,从而返回undefined.

  • Map的键实际是和内存地址绑定的,只要内存地址不一样,就看做为两个键

  • Map的键为简的类型的值时,只要两个值严格相等,就看做为一个键

  • undefinednull也是两个不同的键

  • NaN不严格等于自身,但是Map看做为同一个键

实例的属性和方法

属性
  • size属性返回Map结构的成员总数
操作方法
  • Map.prototype.set(key.value):设置键名key对应的键值value,然后返回整个Map结构,如果key已经有了,则键值会被更新
  • Map.prototype.get(key):获取key对应的键值,如果找不到,则返回undefined.
  • Map.prototype.has(key):返回一个布尔值,表示这个键是否在当前的Map对象中
  • Map.prototype.delete(key):根据键key删除,返回布尔值,表示是否删除成功
  • Map.prototype.clear():清除Map实例的所有成员
遍历方法
  • Map.prototype.keys():返回键名的遍历器
  • Map.prototype.values():返回键值的遍历器
  • Map.prototype.entries():返回所有成员的遍历器
  • Map.prototype.forEach():遍历Map的所有成员

Map结构的默认遍历器是entries()

与其他数据结构相互转换
  • Map转换为数组

使用扩展运算符快速转为数组

const map = new Map().set(true, 7).set({foo:3},['abc']);
[...map]; // [[true,7],[{foo:3},['abc']]]
  • 数组转为Map

将数组传入Map构造函数就可以了

const arr = [[true,7],[{foo:3},['abc']]];
const map = new Map(arr);
  • Map转为对象

当Map的键都是字符串,则无损转为对象

当Map的键有非字符串,那么这个键名会转为字符串,再作为对象的键名

  • 对象转为Map
function objToStrMap(obj){
  const strMap = new Map();
  for (const k of Object.keys(obj)){
    strMap.set(k,obj[k]);
  }
  return strMap;
}

WeakMap

基本用法

WeakMap和Map的区别

  • WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名
  • WeakMap的键名所指向的对象,不计入垃圾回收机制
方法
  • get()
  • set()
  • has()
  • delete()

WeakMap只有上面这四个方法可用。

用途

WeakMap应用的典型场合就是DOM节点作为键名。

let element = document.getElementById('logo');
lt weakMap = new WeakMap();
weakMap.set(element,{timesClicked:0});
element.addEventListener('click',function(){
  let logoData = weakMap.get(element);
  logoData.timesClicked++;
},false);

上面代码中,变量element是DOM节点,每当有click事件发生,就更新一下状态。将这个状态作为键值放在 WeakMap 里,对应的键名就是element。一旦这个 DOM 节点删除,该状态就会自动消失,不存在内存泄漏风险。

备注:本文是自己学习阮一峰老师的《ECMAScript 6 入门》所做的笔记,大部分例子来源于此书。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值