ES6之模拟实现一个Set类

在日常开发中,set 和map 数据结构是用的最多的, 但是都是JS 帮我搞定的,拒绝做api工程师, 接下来就开撸。

基本介绍

ES6 提供了新的数据结构 Set。

它类似于数组,但是成员的值都是唯一的,没有重复的值。

使用场景

  •  数组去重  […new Set(arr)]
  • 数据的唯一性

初始化

Set 本身是一个构造函数, Set 函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。

属性和方法

操作方法有:

  1. add(value):添加某个值,返回 Set 结构本身。
  2. delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
  3. has(value):返回一个布尔值,表示该值是否为 Set 的成员。
  4. clear():清除所有成员,无返回值。

遍历方法:

  1. keys():返回键名的遍历器
  2. values():返回键值的遍历器
  3. entries():返回键值对的遍历器
  4. forEach():使用回调函数遍历每个成员,无返回值

属性: 

size: 返回Set集合的个数

模拟实现第一版

第一版的模拟实现: 

接下来我们开始测试一下:

查看结果: 

符合预期?的。

模拟实现第二版

最麻烦的还是迭代器的实现,Keys, values, 这些方法其实都和Es6的的迭代器有关系。 

迭代器

所谓迭代器,其实就是一个具有 next() 方法的对象,每次调用 next() 都会返回一个结果对象,该结果对象有两个属性,value 表示当前的值,done 表示遍历是否结束。

我们去模拟实现一下呀。

function createIterator(items) {
    let i = 0;
    return {
        next: function() {
            let done = i >= items.length;
            let value = !done ? items[i++] : undefined;
            return {
                done,
                value
            };
        }
    };
}
// test 一下
const a = createIterator([1,2,3]);
console.log(a.next())  // { done: false, value: 1 }
console.log(a.next())  // { done: false, value: 2 }
console.log(a.next())  // { done: false, value: 3 }
console.log(a.next())  // { done: true, value: undefined }
复制代码

OK我们去模拟下keys 和 values

//  这里特别强调的就是, […set.keys()],  这种写法必须返回的对象 加上一个

Symbol.iterator

我们来测试一下我们写的内容: 

let set = new mySet([1, 2, 3]);
let set2 = new Set([1, 2, 3]);
console.log([...set2.keys()], [...set2.values()],[...set2.entries()], '9999')
console.log([...set.keys()], [...set.values()],[...set.entires()], '88888' )
复制代码

直接看截图: 

ok  好像是对的, 以为到这里就大工告成了, 肯定不是, 特殊情况考虑, 如果我传入的是一个数字呢, 这时候我的mySet 是不会报错的, set 接受的参数是可迭代的, 如果不可迭代,是直接会new Error的。

我们如何去判断当前参数是不是可迭代的呢?  判断当前对象有没有Symbol.iterator 并且  Symbol.iterator 是一个function  返回的一个迭代器。 同理我们的mySet 也要在原型上实现迭代器属性: 

最终版

test 一下

let set3 = new mySet([2,3]);
let set4 = new mySet(set3);
console.log(set3, set4);
let set5 = new mySet(5);console.log(set5);
复制代码

查看结果: 

到这里我们的set就写完成了, 如果上面有什么不对的欢迎指正。

总结

本篇例子源码在github上 点击这里 欢迎star, 谢谢大家。

参考:冴羽大佬的这篇文章 传送门

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享