网站首页 > 技术文章 正文
ES6和ES2015
其实很多同学分不大清楚,ES6和ES2015之间的区别,而且目前已经到了ES2022,笔者这里简单地做一个示意。
ES2015的全称是ECMAScript 2015,它表示的是ES6在2015年6月份发布的第一个版本,因此ES6是个历史性的名词,泛指5.1版本后的JavaScript的标准规范,ES2016,2017以及再后面的年份标志的版本都是ES6的范畴。
ECMAScript和JavaScript之间的关系,就是版本规范和具体实现之间的关系,虽然也有其他实现比如ActionScript等等,由于JavaScript实现使用占比广泛的原因,在一般的场合并不会特意去区分它们。
什么是Set
前面讲到了,ES6的第一个版本早在2015年就已经发布了,其中Map和Set就是其中比较常用的特性,以笔者这么些年的体会,其实很多同学都知道,尤其是有Java后端开发经验的同学,但是大家在实操中,使用Map和Set的情况比较不够。究其原因,还是理解不够深刻,并且JavaScript中使用Array和Object毕竟能满足绝大部分场景。
Set
Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。
Set对象是值的集合,可以按照插入的顺序进行迭代,Set中的值是唯一的。
这里讲下MDN中有个很有意思的描述,NaN和undefined是可以存入Set的,但在Set中NaN之间会被认为是重复值,但是NaN!==NaN
我们可以看到,实际的aSet中只有两个值。
Set比较常用的实例方法有add,clear,delete,entires,forEach,has,keys,values等,属性的话就是size,用来返回Set对象中值的个数。这里笔者就不一一进行演示了。我们拿一个大家可能经常会用到的场景来举例。
数组去重
// Use to remove duplicate elements from the array
const numbers = [2,3,4,4,2,3,3,4,4,5,5,6,6,7,5,32,3,4,5]
console.log([...new Set(numbers)])
// [2, 3, 4, 5, 6, 7, 32]
求数组的并集、交集、补集
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
// 并集
let u = new Set([...a, ...b]);
// Set {1, 2, 3, 4}
// 交集
let i = new Set([...a].filter(x => b.has(x)));
// set {2, 3}
// 差集
let d = new Set([...a].filter(x => !b.has(x)));
// Set {1}
WeakSet
仔细研读ES6规范的同学,相信还发现了WeakSet这么个内置对象,接下来我们来一起看看,它是什么,跟Set有什么区别
首先WeakSet对象是一些对象值的集合,并且其中的每个对象值只能出现一次。那就表示跟Set一样,值也是唯一的。
区别
- WeakSet只能存储对象,因此像基本类型就无法存入。
- WeakSet存储的是弱引用,那就意味着WeakSet中的对象,如果没有其他引用,垃圾回收机制会自动该对象所占用的内存。
实例1
基于弱引用的特点,我们有没有具体使用的场景呢?WeakSet 适合临时存放一组对象,以及存放跟对象绑定的信息。只要这些对象在外部消失,它在 WeakSet 里面的引用就会自动消失。
那我们思考下,比如DOM对象的使用,我们打开下百度页面,有个元素Id是s_fm
const a=new WeakSet();
//undefined
a.add(document.getElementById('s_fm'));
//WeakSet {div#s_fm.s_form.s_form_login}
a.has(document.getElementById('s_fm'))
//true
我们向a这个WeakSet中添加这个dom的引用,然后使用has实例方法判断下,这个引用是存在的。
然后我们把这个元素从DOM树上删除,然后再试一下
document.getElementById('s_fm').remove();
//undefined
a.has(document.getElementById('s_fm'))
//false
实例2
再来个MDN上的例子,检测循环引用
递归调用自身的函数需要一种通过跟踪哪些对象已被处理,来应对循环数据结构的方法。
为此,WeakSet非常适合处理这种情况
// 对 传入的subject对象 内部存储的所有内容执行回调
function execRecursively(fn, subject, _refs = null){
if(!_refs)
_refs = new WeakSet();
// 避免无限递归
if(_refs.has(subject))
return;
fn(subject);
if("object" === typeof subject){
_refs.add(subject);
for(let key in subject)
execRecursively(fn, subject[key], _refs);
}
}
const foo = {
foo: "Foo",
bar: {
bar: "Bar"
}
};
foo.bar.baz = foo; // 循环引用!
execRecursively(obj => console.log(obj), foo);
在此,在第一次运行时创建WeakSet,并将其与每个后续函数调用一起传递(使用内部参数_refs)。 对象的数量或它们的遍历顺序无关紧要,因此,WeakSet比Set更适合(和执行)跟踪对象引用,尤其是在涉及大量对象时。
好了,今天的分享就到这里,这个系列的下一期我们聊下还有个被大家遗忘的Map。
大家喜欢的话可以点个关注哦,或者关注下公众号:喵爸的小作坊
猜你喜欢
- 2024-10-16 python数据类型(python数据类型bool)
- 2024-10-16 JavaScript Set、Map、WeakSet 和 WeakMap 的区别?
- 2024-10-16 69-1-10000遗漏了哪些序号#差集#Filter...
- 2024-10-16 进入Python的世界12-常用的程序例子整理二
- 2024-10-16 Java路径-35-Java的HashSet(java路径怎么找)
- 2024-10-16 Redis五种数据类型详解(redis7种数据类型)
- 2024-10-16 那些你不得不知的Redis基础类型常用操作、命令
- 2024-10-16 美团外卖iOS App冷启动治理(美团早启动)
- 2024-10-16 (Python)通过口诀记忆数组、集合、字典、元组
- 2024-10-16 【C++泛型编程】(二)标准模板库 STL
- 04-29kali2021ping 外网不通
- 04-29我是如何用这3个小工具,助力小姐姐提升100%开发效率的
- 04-29注册下载啊
- 04-29Spring 中三种 BeanName 生成器!
- 04-29mysql学习9:创建数据库
- 04-29Linux之yum源详解
- 04-29夏日终曲/请以你的名字呼唤我/Call me by your name(无剧透)
- 04-29注释竟然还有特殊用途?一文解惑 //go:linkname 指令
- 最近发表
- 标签列表
-
- cmd/c (64)
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- sqlset (59)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)