const mySet = (() => { /** * 设置私有属性 */ const getObj = Symbol('getObj') const data = Symbol('data') const isEqual = Symbol('isEqual') /** * 将其手写的 Set返回出去 */ return class mySet { /** * 使用Myset需要传递进去一个可迭代对象 * @param {*} iterable */ constructor(iterable = []) { if (typeof iterable[Symbol.iterator] !== 'function') { throw new TypeError('arguments is not an iterator') } this[data] = [] for (const item of iterable) { this.add(item) } } /** * 添加 * @param {*} key */ add(key) { if (!this[getObj](key)) { this[data].push(key) } } /** * 检查是否存在对应的数据 * @param {*} key * 返回值为 true false */ has(key) { return this[getObj](key); } /** * 检索数据 * @param {*} key * 返回值为 true false */ [getObj](key) { for (const item of this[data]) { if (this[isEqual](item, key)) { return true; } } return false } /** * 删除对应的数据 * @param {*} key * 返回值为 true false */ delete(key) { for (let i = 0; i < this[data].length; i++) { const item = this[data][i]; if (this[isEqual](key, item)) { this[data].splice(i, 1) return true; } } return false; } /** * 清空数据 */ clear() { this[data].length = 0; } /** * 获取的数据的数量与arr.length 一个意思 */ get size() { return this[data].length; } /** * 遍历数据 * @param {*} callback * 与数组的forEach不同,数组中的forEcast的第一个参数为索引值,此处无索引值,用其数据代替 */ forEach(callback) { for (const iterator of this[data]) { callback(iterator, iterator, this) } } /** * 检查是否拥有数据是否相同 * @param {*} data1 * @param {*} data2 * 返回值为 true false */ [isEqual](data1, data2) { if (data1 === 0 && data2 === 0) { return true; } return Object.is(data1, data2); } /** * 生成器 * 使其成为可迭代对象 */ *[Symbol.iterator]() { for (const iterator of this[data]) { yield iterator; } } }})()