前言
ES6,即ECMAScript 2015,是JavaScript的一个新标准,引入了许多新的特性和语法,旨在提高开发效率和代码质量。从更简洁的箭头函数到强大的模块系统,ES6为现代Web开发带来了革命性的变化。与此同时,也带来了更多的面试重点,从本篇文章开始我们将逐步解析ES6,全面认识ES6,通过简单易懂的方式拿下其中面试重点。
一,Set
有以下几个基本性质:
- 唯一性:
Set对象中的元素是唯一的,每个元素只会出现一次。如果尝试添加已存在的元素,Set不会改变。 - 无序性:
Set对象中的元素是无序的,即元素的插入顺序和迭代顺序可能不同。 - 可迭代性:
Set对象是可迭代的,因此可以使用for...of循环来遍历其元素。
1.基本方法
size:返回元素的个数
const s = new Set([1, 2, 3, 4])
console.log(s.size);//4
add(value):添加元素,返回 Set 对象本身
const s = new Set([1, 2, 3, 4])
s.add(5)
console.log(s);
//Set(5) { 1, 2, 3, 4, 5 }
delete(value):删除某个元素
const s = new Set([1, 2, 3, 4])
s.delete(1)
console.log(s);//Set(3) { 2, 3, 4 }
has(value):返回一个布尔值,表示某个值是否存在
const s = new Set([1, 2, 3, 4])
console.log(s.has(1));//true
clear():清除所有元素
const s = new Set([1, 2, 3, 4])
console.log(s.clear(s));//undefined
2.除重方法
a,数组除重
1.new Set(arr))
将原数组转变为一个Set对象,利用Set对象的唯一性----在JS中,Set 对象是一个值的集合,每个值在Set中只会出现一次。因此,当你创建一个Set并传入一个包含重复元素的数组时,重复的元素会被自动去重。
const arr = [1, 2, 3, 4, 4, 3, 2, 1]
console.log(new Set(arr))
//Set(4) { 1, 2, 3, 4 }
2.解构[...new Set(arr)]
将原数组转变为Set对象这一步显然不能达到我们的目标,因为他返回的是一个 Set 对象,我们还需要将这个对象解构然后放到一个新数组中
const arr = [1, 2, 3, 4, 4, 3, 2, 1]
const arr2 = [...new Set(arr)]
console.log(arr2);
//[ 1, 2, 3, 4 ]
所以我们可以总结以下三步:
- 将原数组转变为Set对象,去重
- 将Set对象解构,并转换为数组(
...,[]) - 将新的数组赋值给新的变量
b,字符串除重
1.[...new Set(str)].join('')
对于字符串来说,前几个步骤是一样的
- 将原数组转变为Set对象,去重
- 将Set对象解构,并转换为数组(
...,[]);此时得到[ 'a', 'b', 'c' ] join('')方法将数组中的元素连接成一个新的字符串;得到abc- 将新的数组赋值给新的变量
const str = 'abcabc'
const str2 = [...new Set(str)].join('')
console.log(str2);
//abc
3.遍历方法
1.通过for of遍历
const s = new Set([1,2,3,3]) // 重复的3会被自动去重
for(let item of s){
console.log(item);
}
//1
//2
//3
如果直接用for遍历?
可以通过先将Set转换为数组,然后再进行遍历。但是请注意,这样做会失去Set的一些特性,比如元素的唯一性保证。
const s = new Set([1, 2, 3, 3]);
const arrayFromSet = Array.from(s); // 或者 [...s] 使用扩展运算符
for (let i = 0; i < arrayFromSet.length; i++) { console.log(arrayFromSet[i]); }
2.使用本身存在的keys()、values()、entries() 和 forEach()四种遍历方法,
keys()、values()
(效果相同)
一次遍历
const s = new Set([1, 2, 3, 3]);
console.log(s.keys());
//console.log(s.values());
二次遍历
const s = new Set([1, 2, 3, 3]);
for (let key of s.keys()) {
console.log(key);
}
//for (let value of s.values()) {
//console.log(value);
//}
entries()
一次遍历
const s = new Set([1, 2, 3, 3]);
console.log(s.entries());
二次遍历
const s = new Set([1, 2, 3, 3])
for (let [key, value] of s.entries()) {
console.log(key, value);
}
forEach()
const s = new Set([1, 2, 3, 3])
s.forEach(console.log);
二,强引用和弱引用
弱引用(Weak References)和强引用(Strong References)在编程中是对对象引用方式的两种不同分类,它们的主要区别在于对垃圾回收器(Garbage Collector)的影响以及对象的生命周期管理
垃圾回收机制的算法不受人类掌控,可能突然生效又突然被清理
区别总结
- 稳定性:强引用是稳定的,只要引用存在,对象就不会被回收;而弱引用是非稳定的,对象可能被随时回收。
- 垃圾回收:强引用会阻止垃圾回收器回收对象;而弱引用不会阻止,只要没有其他强引用指向对象,对象就可能被回收。
- 用途:强引用是日常编程中常用的引用方式;而弱引用通常用于实现缓存(如LRU缓存),以避免内存泄漏,或者用于观察对象是否被垃圾回收(例如,在调试和诊断工具中)。
- 生命周期管理:强引用直接管理对象的生命周期;而弱引用则是一种更间接、更灵活的管理方式。
三,weakSet
- 由于WeakSet中的引用是弱引用,因此它不适合用于需要长期存储引用的场景。
- WeakSet没有提供遍历方法,因此无法直接获取其包含的所有元素。
- WeakSet在初始化时不能通过赋值来填充,只能通过
add方法逐个添加元素
四,面试
面试题一:set和weakset的区别
- Set:对元素的引用是强引用,即Set中的元素在Set存在期间不会被垃圾回收机制回收。
- WeakSet:对元素的引用是弱引用。如果没有其他对WeakSet中对象的引用存在,那么这些对象会被垃圾回收。即WeakSet不会阻止垃圾回收。
面试题二:结合弱引用的垃圾回收原理详细说明
- 一个对象obj存放在其他的结构中,当后续存在其他对象引用这个对象,那么这个对象的内存就不会被回收
- 一个对象obj存在其他结构中,当后续只存在WeakSet对他的引用,该对象的内存依然会被回收
适用场景:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="wrap">
<button id="btn">确定
</div>
</div>
<script>
let wrap = document.getElementById("wrap")
let btn = document.getElementById("btn")
//给按钮打上禁用标签
const disabledEls = new Set()//new WeakSet
disabledEls.add(btn)
//按钮点击就消失
btn.addEventListener("click", () => {
wrap.removeChild(btn)
})
</script>
</body>
</html>
在以上代码中,按钮被点击就会消失,btn不会再被引用但。但是第20行使用的是Set()强引用,当代码执行完毕时第17行这一无用代码的Dom结构会一直留在内存中,我们可以将第20行的Set()强引用变为WeakSet()弱引用,WeakSet()会给17行打上null标签,当代码执行完成后垃圾回收机制会第一时间清理他。
五,map
可以使用任意的数据类型作为key,弥补了传统对象只能使用字符串做key的缺陷
基本方法
set(key, value):设置 Map 中某个键的值,返回 Map 对象本身get(key):返回 Map 中某个键对应的值,如果该键不存在则返回undefined
同样具有set的方法:
size:返回 Map 中键值对的个数has(key):返回一个布尔值,表示某个键是否存在于 Map 中delete(key):删除 Map 中的某个键值对,返回一个布尔值表示删除是否成功clear():清除 Map 中的所有键值对
遍历方法,和set一样
四种遍历方法: keys()、values()、entries() 和 forEach()
const m = new Map();
const o = { age: 18 }
m.set(o, [1, 2, 3])
console.log(m.keys());
//console.log(m.values());
//console.log(m.entries());
//console.log(m.forEach());
以下是对应输出结果: