-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ES6 系列之模拟实现一个 Set 数据结构 #91
Comments
学习了 加油共勉! |
set实现最终版怎么forEach写了两遍? |
|
第二版执行代码: set.add(NaN); set.add(NaN); 两次console的set.size应该是4 |
很赞呢 |
NAN处理为啥不用includes来代替indexOf |
另外我感觉Set应该用Map实现比较好吧 |
@vnues 没记错的话,java里面好像就是用map实现的。 |
|
使用map的话,js的对象在遍历时是无序的,Set的规范里要求要按add的顺序来遍历 |
可以实现,你如果打印一下就会发现set的顺序会map的顺序是一样的 |
基本介绍
ES6 提供了新的数据结构 Set。
它类似于数组,但是成员的值都是唯一的,没有重复的值。
初始化
Set 本身是一个构造函数,用来生成 Set 数据结构。
Set 函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。
属性和方法
操作方法有:
举个例子:
之所以每个操作都 console 一下,就是为了让大家注意每个操作的返回值。
遍历方法有:
注意 keys()、values()、entries() 返回的是遍历器
属性:
模拟实现第一版
如果要模拟实现一个简单的 Set 数据结构,实现 add、delete、has、clear、forEach 方法,还是很容易写出来的,这里直接给出代码:
我们可以写段测试代码:
模拟实现第二版
在第一版中,我们使用 indexOf 来判断添加的元素是否重复,本质上,还是使用 === 来进行比较,对于 NaN 而言,因为:
模拟实现的 Set 其实可以添加多个 NaN 而不会去重,然而对于真正的 Set 数据结构:
所以我们需要对 NaN 这个值进行单独的处理。
处理的方式是当判断添加的值是 NaN 时,将其替换为一个独一无二的值,比如说一个很难重复的字符串类似于
@@NaNValue
,当然了,说到独一无二的值,我们也可以直接使用 Symbol,代码如下:写段测试用例:
模拟实现第三版
在模拟实现 Set 时,最麻烦的莫过于迭代器的实现和处理,比如初始化以及执行 keys()、values()、entries() 方法时都会返回迭代器:
而且 Set 也支持初始化的时候传入迭代器:
当初始化传入一个迭代器的时候,我们可以根据我们在上一篇 《ES6 系列之迭代器与 for of》中模拟实现的 forOf 函数,遍历传入的迭代器的 Symbol.iterator 接口,然后依次执行 add 方法。
而当执行 keys() 方法时,我们可以返回一个对象,然后为其部署 Symbol.iterator 接口,实现的代码,也是最终的代码如下:
写段测试代码:
QUnit
由上我们也可以发现,每当我们进行一版的修改时,只是写了新的测试代码,但是代码改写后,对于之前的测试代码是否还能生效呢?是否不小心改了什么导致以前的测试代码没有通过呢?
为了解决这个问题,针对模拟实现 Set 这样一个简单的场景,我们可以引入 QUnit 用于编写测试用例,我们新建一个 HTML 文件:
编写测试用例,因为语法比较简单,我们就直接看编写的一些例子:
用浏览器预览 HTML 页面,效果如下图:
完整的 polyfill 及 Qunit 源码在 https://github.com/mqyqingfeng/Blog/tree/master/demos/qunit。
ES6 系列
ES6 系列目录地址:https://github.com/mqyqingfeng/Blog
ES6 系列预计写二十篇左右,旨在加深 ES6 部分知识点的理解,重点讲解块级作用域、标签模板、箭头函数、Symbol、Set、Map 以及 Promise 的模拟实现、模块加载方案、异步处理等内容。
如果有错误或者不严谨的地方,请务必给予指正,十分感谢。如果喜欢或者有所启发,欢迎 star,对作者也是一种鼓励。
The text was updated successfully, but these errors were encountered: