JavaScript学习笔记(十三):set和map

一、Set

ES6中新增的Set是一种新集合类型,Set在很多方面都像是加强的Map,类似于数组,但是Set中不能存放重复的值

创建set

Set本身也是一个构造函数,因此可以通过new来生成Set实例,Set函数可以接受一个数组(或具有Iterable接口的其他数据结构)作为参数,来初始化Set实例

{
	let set = new Set([1,2,3,4,5]);
	for(let v of set){
		console.log(set); // 1 2 3 4 5
	}
	console.log([...set]); // [1,2,3,4,5]
}
{
	// set可以去掉数组中重复的值
	let items = new Set([1,2,3,5,4,6,8,1,3]);
	console.log([...items]); // [1,2,3,5,4,6,8]

	// 去掉字符串中重复字符
	let str = 'aabbccdd';
	console.log([...new Set(str)].join("")); // abcd
}

set的属性与方法

属性:

  • constructor:构造函数,默认就是Set函数
  • size:返回Set实例的成员数量

方法

  • 操作方法,用于操作数据
    • add(value):添加值,返回该Set实例的引用
    • delete(value):删除值,返回一个布尔值,表示删除是否成功
    • has(value):返回一个布尔值,表示该值是否是Set实例的成员
    • clear():清楚所有成员,没有返回值
  • 遍历方法,用于遍历成员
    • keys():返回键名的遍历器
    • values():返回键值的遍历器(因为Set结构没有键名,只有键值,因此keys方法和values方法完全一致)
    • entries():返回键值对的遍历器
    • forEach():使用回调函数遍历每个成员,没有返回值
{
	let set = new Set();
	set.add(1).add(2).add(3);
	console.log(set); // Set(3) {1, 2, 3}

	console.log(set.has(2)); // true
	console.log(set.has(3)); // true
}
{
	// 遍历方法
	let set = new Set(['red','blue','green']);
    for (const item of set.keys()) {
        console.log(item); // red blue green
    }
    for (const item of set.values()) {
        console.log(item); // 与上面一样
    }
    for (const item of set.entries()) {
        console.log(item); // [ 'red', 'red' ] [ 'blue', 'blue' ] [ 'green', 'green' ]
    }
    set.forEach((item) => console.log(item.toUpperCase())) // RED BLUE GREEN
    set.forEach((item,key,set) => {
        console.log(set.size); // 3
    })
}

set遍历的应用

扩展运算符和Set结构相结合,就可以去除数组的重复成员

{
	let arr = [2,3,54,4,3,2,4];
	arr = [...new Set(arr)];
	console.log(arr); // [ 2, 3, 54, 4 ]
}

Set实例可以间接的使用数组的map和filter方法

{
    let ns = new Set([1,2,3,4]);
    ns = new Set([...ns].map(x => x * 2));
    console.log(ns); // Set(4) { 2, 4, 6, 8 }

    ns = new Set([...ns].filter(x => x > 2));
    console.log(ns); // Set(3) { 4, 6, 8 }
}

扩展运算符、map、filter和Set结构相结合实现并集、交集、差集

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

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

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

set垃圾回收机制

引用类型的数据如果没有使用了,那么就会被系统的垃圾回收机制回收掉

{
	let = obj = {name:"Tom"};
	let newObj = obj;
	obj = null;
	console.log(newObj); // {name:"Tom"}还有,因为还在使用
	newObj = null;
    console.log(newObj); // null没有了
}

WeakSet

WeakSet与Set的区别

  • WeakSet的成员只能是对象
  • WeakSet中的对象都是弱引用
    • 垃圾回收机制不考虑WeakSet对该对象的引用
    • 如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收对象所占用的内存
  • 应用场景
    • WeakSet适合临时存放一组对象,以及存放跟对象绑定的信息
    • 只要这些对象在外部消失,它在WeakSet里面的引用就会自动消失
  • ES6规定WeakSet不可遍历
在这里插入代码片

二、Map

Map类型是键值对的有序列表,而键和值都可以是任意类型
相较于Object

  • Object只能用字符串当做键,其他类型作为键会自动转换为字符串,相当于字符串-值
  • Map可以直接使用各种类型的值(包括对象)作为键
  • Object重在表达对象,Map重在表达数据结构-字典

Map的基本用法

  • set(key,value):设置键值对
  • get(key):通过key获取对应的值
  • 类似Set的方法和属性:has(key)、delete(key)、clear()、size
{
	let map = new Map();
	map.set("name","Tom");
	map.set({},"Object");
	map.set(function(){},"func");
	console.log(map);
}

在这里插入图片描述
Map构造函数可以接收一个数组作为参数,该数组的成员是一组表示键值对的数组

{
	let map = new Map([['one','tow'],['hello',"world"]]) //有多少个数组就有多少个数组里面的键值对 
    console.log(map); // 数组的第一个元素为key,第二个元素为value Map(2) { 'one' => 'tow', 'hello' => 'world' }
}

不仅仅是数组,任何具有Iterator接口、且每个成员都是一个双元素的数组的数据结构都可以作为Map构造函数的参数。

只有对同一个对象的引用,Map才会认为是同一个键,Map的键实际上是和内存地址绑定的,只要内存地址不一样,就是两个键。

{
    const mm = new Map();
    mm.set(["a"], 5);
    console.log(mm.get(["a"])); // undefined,不是同一个引用,因此获取不到
    const k1 = {};
    const k2 = {};
    mm.set(k1, 100);
    mm.set(k2, 200);
    console.log(mm.get(k1), mm.get(k2)); // 同一个引用,100  200
}

如果Map的键是一个简单类型的值(布尔、字符串、数值)只要两个值严格相等,那么Map就认为是同一个键

遍历方法

Map结构原生提供三个遍历器生成函数和一个遍历方法

  • keys():返回键名的遍历器
  • values():返回键值的遍历器
  • entries():返回键值对的遍历器
  • forEach():使用回调函数遍历每个成员,没有返回值
  • Map结构的默认遍历器接口(Symbol.iterator属性)就是entries方法
{
	let map = new Map();
    map.set('name','tom').set('age',20);
    console.log(map);
    for (const iterator of map) {
        console.log(iterator); // [ 'name', 'tom' ] [ 'age', 20 ]
    }
    for (const iterator of map.entries()) {
        console.log(iterator); // 与上面一样
    }
}
{
	// 与Set一样,Map也可以利用扩展运算符转换为数组,从而使用数组的方法
	let map = new Map();
    map.set('a',100).set('b',200).set('c',300);
    console.log(map); // Map(3) { 'a' => 100, 'b' => 200, 'c' => 300 	}
    
    let map1 = new Map([...map].filter(([k,v]) => v > 100));
    console.log(map1); // Map(2) { 'b' => 200, 'c' => 300 }
}

与其他数据结构的相互转换

Map转换为数组

{
	let map = new Map().set('a',100).set('b',200);
	console.log([...map]);

	// 数组转为Map
    let myMap = new Map([['a',1],[{b:'1'},2]]);
    console.log(myMap); // Map(2) { 'a' => 1, { b: '1' } => 2 }
}

WeakMap

WeakMap与Map的区别

  • WeakMap只接受对象作为键名(null)除外,不接受其他类型的值作为键名
  • WeakMap的键名所指向的对象,不会计入垃圾回收机制
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值