ES6之手写map

59 阅读1分钟

ES6之手写map

class MyMap {
    constructor(iterable = []) {
        //验证是否是可迭代的对象
        if (typeof iterable[Symbol.iterator] !== "function") {
            throw new TypeError(`你提供的${iterable}不是一个可迭代的对象`)
        }
        this._datas = [];
        for (const item of iterable) {
            //判断里面是否是可迭代对象
            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) {
        if (this._getObj(key)) {
            //修改key对应的值
            this._getObj(key).value = value;
        } else {
            this._datas.push({
                key,
                value
            })
        }
    }
    has(key) {
        //如果有对象,返回true
        return this._getObj(key) !== undefined;
    }
    get(key) {
        //如果对应的键有值,返回
        const obj = this._getObj(key);
        if (obj) {
            return obj.value;
        }
    }
    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;
    }
    get size() {
        return this._datas.length;
    }
    *[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);
        }
    }
    /**
     * 判断是否有key,返回数组中对应的对象
     * @param {*} key 
     * @returns 
     */
    _getObj(key) {
        for (const item of this._datas) {
            if (this.isEqual(item.key, key)) {
                return item;
            }
        }
    }
    /**
     * 判断两个是否相等
     * @param {*} data1 
     * @param {*} data2 
     * @returns 
     */
    isEqual(data1, data2) {
        //先判断+0和-0,剩下的使用object.is
        if (data1 === 0 && data2 === 0) {
            return true;
        } else {
            return Object.is(data1, data2);
        }
    }
}

map 集合和 set 集合类似。我们需要在传入的可迭代对象的遍历中继续判断一次是否是可迭代对象。同时,封装一个函数用来获取 key 键对应的数组对象。注意:set 方法添加键值对,需要两次迭代得到。如果没有 key 键进行添加,如果有 key 键改变 key 键对应的值。forEach 方法遍历调用回调函数,第一项是值,第二项是键,第三项是 map 集合。创建 Symbol.iterator 生成器函数,每一次迭代拿出 key 键和 value 值。