手动实现es6的set集合 模拟set集合实现对应的功能

 // 底层实现set, 手写实现set, 为了更加深刻的理解set集合
 class MySet {
            // 此处定义一个数组来模拟set, 原生的set是用c或者c++ 可以操作浏览器底层的设计
            _datas = Symbol("内部维护一个数组来模拟set")
            // 这里用户可以传入参数,也可以不传递参数
            constructor(iterator = []) {
                if (typeof iterator[Symbol.iterator] !== "function") {
                    // 判断传入的参数是否是一个可迭代的对象, 因为可迭代对象里面一定有一个知名符号的函数
                    return new Error(`你传入的${iterator}不是以恶可迭代对象`);
                }
                this._datas = [];
                // 传入的是一个迭代对象,那么进行遍历,放入MySet 的数组里面
                for (const item of iterator) {
                    // 添加到数组里面
                    this.add(item);
                }
            }
            /**
             * @description:  往set 里面添加一个数据
             * @param : 添加的数据
             * @return: {boolean} 结果
             */
            add(data) {
                // 添加一个数据,要判断set里面是否已经存在该数据了
                if (!this.has(data)) {
                    this._datas.push(data);
                    return this._datas;
                }
                return this._datas;
            }
            /**
             * @description: 判断set集合内部里面是否存在某个元素
             * @param :  data 数据
             * @return: {boolean} 结果
             */
            has(data) {
                for (const item of this._datas) {
                    if (this.isEqual(data, item)) {
                        return true;
                    }
                }
                return false;
            }

            /**
             * @description:  判断两个数据是否相同
             * @param :  data1 数据1
             * @param :  data2  数据2
             * @return:  {boolean} 
             */
            isEqual(data1, data2) {
                // 因为set 内部+0 和 -0 是经过特殊测合理的,所以此处这样老模拟
                if (data1 === 0 && data2 === 0) {
                    return true;
                }
                // 如果比较的两个值不是0,则使用Oject.is
                return Object.is(data1, data2)
            }

            /**
             * @description: 删除set里面的某个值
             * @param : data
             * @return: boolean 结果
             */
            delete(data) {
                for (let i = 0; i < this._datas.length; i++) {
                    const element = this._datas[i];
                    if (this.has(data)) {
                        this._datas.splice(i, 1);
                        return true;
                    } else {
                        return false;
                    }
                }
            }
            /**
             * @description: 清空set
             */
            clear() {
                this._datas.length = 0;
                return this._datas;
            }
            /**
             * @description:  因为set本身也是一个可迭代的对象,生成器来构建一个迭代对象,
             使用方法: 直接调用该生成器方法,就可以创建一个可迭代的对象
             */
            *[Symbol.iterator]() {
                for (const item of this._datas) {
                    yield item;
                }
            }
            /**
             * @description:  为了实现set 的forEach() 方法, 
             注意forEach() 第一二参数和第二个参数是一样的,因为set集合不存在下标
             * @param : 
             * @return: 
             */
            forEach(callback) {
                for (const item of this._datas) {
                    callback(item, item, this._datas);
                }
            }
		 // 获取size的长度
            get size(){
                return this._datas.length;
            }
        }
    // 使用方法,和set 的使用方法一样
        const arr = [1, 2, 3, 4, 1, 2, 3, 4];
        const ms = new MySet(arr);
        console.log(ms)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章