ES6学习8(Set&Map)

本文详细介绍了ES6中的Set和Map数据结构,包括Set的实例属性和方法、遍历操作、集合操作,以及WeakSet的特性和方法。Map部分涵盖了其属性、方法及遍历方式,同时提到了WeakMap的使用场景和方法。文章强调了Set和Map在处理键值对时的灵活性,以及WeakSet和WeakMap在内存管理上的优势。
摘要由CSDN通过智能技术生成

Set

var s = new Set();
[2, 3, 5, 4, 5, 2, 2].map(x => s.add(x));
for (let i of s) {
  console.log(i);
}
// 2 3 5 4

Set函数可以接受一个数组(或类似数组的对象)作为参数,用来初始化。

// 初始化
var items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
[...set]// [1, 2, 3, 4, 5]

// 初始化
function divs () {
  return [...document.querySelectorAll('div')];
}
var set = new Set(divs());

向Set加入值的时候,不会发生类型转换,所以5和”5”是两个不同的值。

实例属性和方法

Set.prototype.constructor:构造函数,默认就是Set函数。
Set.prototype.size:返回Set实例的成员总数。
add(value):添加某个值,返回Set结构本身。
delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
has(value):返回一个布尔值,表示该值是否为Set的成员。
clear():清除所有成员,没有返回值。
Array.from方法可以将Set结构转为数组。

遍历操作

keys():返回键名的遍历器
values():返回键值的遍历器
entries():返回键值对的遍历器
forEach():使用回调函数遍历每个成员

let set = new Set(['red', 'green', 'blue']);
for (let item of set.keys()) {
  console.log(item);
}
// red
// green
// blue
for (let item of set.values()) {
  console.log(item);
}
// red
// green
// blue
for (let item of set.entries()) {
  console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]
//Set结构的实例默认可遍历,它的默认遍历器生成函数就是它的values方法
//所以直接用for of就可以循环它
for (let x of set) {
  console.log(x);
}

集合操作

let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}

// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// set {2, 3}

// 差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1}

WeakSet

WeakSet结构与Set类似,也是不重复的值的集合。
WeakSet的成员只能是对象,而不能是其他类型的值。
WeakSet中的对象都是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于WeakSet之中。这个特点意味着,无法引用WeakSet的成员,遍历机制也无法保证成员的存在,很可能刚刚遍历结束,成员就取不到了。
WeakSet的一个用处,是储存DOM节点,而不用担心这些节点从文档移除时,会引发内存泄漏。

var ws = new WeakSet();
ws.add(1)
// TypeError: Invalid value used in weak set
ws.add(Symbol())
// TypeError: invalid value used in weak set
var b = [3, 4];
var ws = new WeakSet(b);
// Uncaught TypeError: Invalid value used in weak set(…)
var a = [[1,2], [3,4]];
var ws = new WeakSet(a);

方法

由于不可遍历,也就没有size属性了。
WeakSet.prototype.add(value)
WeakSet.prototype.delete(value)
WeakSet.prototype.has(value)

Map

JS有Object,但是只能用字符串作为键。
Map可以用各种类型可Hash的值作为键。
Map的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。这就解决了同名属性碰撞(clash)的问题,我们扩展别人的库的时候,如果使用对象作为键名,就不用担心自己的属性与原作者的属性同名。

//初始化
var m = new Map();
var o = {};
var s = {};
m.set(o, 'content');
m.set(s, 'other');
console.log(m.get(o)) // "content"
console.log(m.get(s)) // "other"

//利用键值对数组初始化
var map = new Map([
  ['name', '张三'],
  ['title', 'Author']
]);
map.size // 2
map.has('name') // true
map.get('name') // "张三"
map.has('title') // true
map.get('title') // "Author"

属性和方法

size
set(key, value)这个方法返回本map,可以链式调用

let map = new Map()
  .set(1, 'a')
  .set(2, 'b')
  .set(3, 'c');
console.log(map);

get(key)
has(key)
delete(key)
clear()

遍历

keys():返回键名的遍历器。
values():返回键值的遍历器。
entries():返回所有成员的遍历器。
forEach():遍历Map的所有成员。
需要特别注意的是,Map的遍历顺序就是插入顺序。
使用拓展运算符可以快速将Map的键值转为数组:

console.log([...map.keys()]);
// [1, 2, 3]

console.log([...map.values()]);
// ['one', 'two', 'three']

console.log([...map.entries()]);
// [[1,'one'], [2, 'two'], [3, 'three']]

console.log([...map]);
// [[1,'one'], [2, 'two'], [3, 'three']]

WeakMap

WeakMap结构与Map结构基本类似,唯一的区别是它只接受对象作为键名(null除外),不接受其他类型的值作为键名,而且键名所指向的对象,不计入垃圾回收机制。
WeakMap的设计目的在于,键名是对象的弱引用(垃圾回收机制不将该引用考虑在内),所以其所对应的对象可能会被自动回收。当对象被回收后,WeakMap自动移除对应的键值对。典型应用是,一个对应DOM元素的WeakMap结构,当某个DOM元素被清除,其所对应的WeakMap记录就会自动被移除。基本上,WeakMap的专用场合就是,它的键所对应的对象,可能会在将来消失。WeakMap结构有助于防止内存泄漏。
WeakMap同样是不可遍历的呦
只有get()、set()、has()、delete()4个方法。
下面这个例子用一个DOM节点当做键,记录它被点击的次数,当这个节点不存在时,这个键值就自动消失了。

let myElement = document.getElementById('logo');
let myWeakmap = new WeakMap();

myWeakmap.set(myElement, {timesClicked: 0});

myElement.addEventListener('click', function() {
  let logoData = myWeakmap.get(myElement);
  logoData.timesClicked++;
  myWeakmap.set(myElement, logoData);
  console.log(myWeakmap.get(myElement).timesClicked);
}, false);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值