SOURCE

class mySet {
    constructor(optionArr = []) {
        //必须传入一个可迭代的数据
        if(typeof optionArr[Symbol.iterator] !== 'function') {
            throw new TypeError(`你提供的${optionArr}不是一个可迭代的对象`);
        }
        this.list = {};
        this.size = optionArr.length;
        optionArr.forEach( val => {
            this.list[val] = val
        })
    }
    add(val) {
        if(!this.list[val]) {
            this.list[val] = val;
            this.size ++;
            return true
        }
        return false
    }
    has(val) {
        //判断是否是对象 是的话返回false
        if(val !== null && typeof val == 'object') return false;
        return this.list.hasOwnProperty(val)
    }
    delete(val) {
        if(this.list[val]) {
            delete this.list[val];
            this.size --;
            return true
        }
        return false
    }
    clear(val) {
        this.list = {};
        this.size = 0
    }
    //keys和value是一样的
    keys() {
        return Object.values(this.list)
    }
    values() {
        return Object.values(this.list)
    }
    entries() {
        return Object.entries(this.list).map( item => {
            item[0] = item[1]
            return item
        })
    }
    forEach(callback) {
        let keys = this.keys();
        for(const key of keys) {
            callback(key, key, this)
        }
    }
}
const set = new mySet([
 [1],
 [2]
])
console.log(set.size)
set.forEach((key, value) => {
    console.log(key + '--' + value)
})
set.keys((key) => {
    console.log(key)
})

//-------------------------------
class myMap {
    constructor(optionArr = []) {
        if(typeof optionArr[Symbol.iterator] !== 'function') {
            throw new TypeError(`${optionArr} 不是可迭代数据`)
        }
        this._datas = [];
        for(const item of optionArr) {
            //item也得是一个可迭代对象
            if(typeof item[Symbol.iterator] !== 'function') {
                throw new TypeError(`${item} 必须是一个可迭代的对象`)
            }
            const iterator = item[Symbol.iterator]();
            //不一定是数组 所以需要用这种方式取出key value
            const key = iterator.next().value;
            const value = iterator.next().value;
            this.set(key, value)
        }
    }
    set(key, value) {
        const obj = this._getobj(key)
        if(obj) {
            obj.value = value
        }
        else {
            this._datas.push({
                key,
                value
            })
        }
    }
    get(key) {
        const item = this._getobj(key);
        if(item) return this.item.value
        return undefined;//找不到
    }
    get size() {
        return this._datas.length;
    }
    delete(key) {
        for(let i = 0; i < this._datas.length; i++) {
            const element = this._datas[i];
            if(this.isEqual(element.key, key)) {
                this._datas.splice(i, 1);
                return true
            }
        }
        return false;
    }
    clear() {
        this._datas.length = 0;
    }
    /**
     * 根据key从内部数组中 找到对应的数组项
     */
    _getobj(key) {
        for(const item of this._datas) {
            if(this.isEqual(item.key, key)) {
                return item
            }
        }
    }
    has(key) {
        return this._getobj(key) !== undefined
    }
    //判断两个数是否相等
    isEqual(data1, data2) {
        if(data1 == 0 && data2 == 0) {
            return true
        }
        return Object.is(data1, data2)
    }
    *[Symbol.iterator]() {
        //迭代器创建函数本身就是生成器函数
        for(const item of this._datas) {
            yield [item.key, item.value]
        }
    }
    forEach(callback) {
        for(const item of this._datas) {
            callback(item.value, item.key, this)
        }
    }
    keys() {
       // return this._datas
        return this._datas.map( item => item.key)
    }
    values() {
        return this._datas.map( item => item.value)
    }
    entries() {
        return this._datas.map( item => [item.key, item.value])
    }
}
console 命令行工具 X clear

                    
>
console