>[success] # JS 字典 ~~~ 1.字典是一种[键,值]对的形式来存储数据结构,这么感觉和js 对象没有太大的区别 ,但实际区别字典的建也是可以为对象,就类似js 中的Map 一样 ~~~ >[danger] ##### 案例看一下js对象和Map最大的区别 ~~~ const obj = {} const keyA = {'a':1} const keyB ={'b':1} obj[keyA] = 2 obj[keyB] = 3 console.log(obj[keyA]) // 3 因为对象的key 都是toString 类型 const map = new Map() map.set(keyA,2) map.set(keyB,3) console.log(map.get(keyA)) // 2 ~~~ >[info] ## 自己实现一个字典 ~~~ 1.字典和Map很像,都是可以存储键值对的形式,实现一个dic 字典类 ~~~ >[danger] ##### 实现字典的方法 ~~~ 1.set(key,value):向字典中添加新元素。如果 key 已经存在,那么已存在的 value 会 被新的值覆盖。 2.remove(key):通过使用键值作为参数来从字典中移除键值对应的数据值。 3.hasKey(key):如果某个键值存在于该字典中,返回 true,否则返回 false。 4.get(key):通过以键值作为参数查找特定的数值并返回。 5.clear():删除该字典中的所有值。 6.size():返回字典所包含值的数量。与数组的 length 属性类似。 7.isEmpty():在 size 等于零的时候返回 true,否则返回 false。 8.keys():将字典所包含的所有键名以数组形式返回。 9.values():将字典所包含的所有数值以数组形式返回。 10.keyValues():将字典中所有[键,值]对返回。 11.forEach(callbackFn):迭代字典中所有的键值对。callbackFn 有两个参数:key 和 value。该方法可以在回调函数返回 false 时被中止(和 Array 类中的 every 方法相似)。 ~~~ >[danger] ##### 代码实现 ~~~ 1.要注意我们实现的字典依然是无法将不同对象根据key 来区分,如果想实际区分需要手动重写 要作为对象key 的toString 方法 2.存储的格式'{key:{key:key,value:value}}' 3.defaultToString 方法会专门将key 转换成字符串的方法 4.ValuePair 专门保存整个key value 形成对象的方法 ~~~ ![](https://img.kancloud.cn/9d/18/9d18d7993b7244c47673c0fb732888c8_357x113.png) ~~~ function defaultToString(item) { if (item === null) { return 'NULL'; } if (item === undefined) { return 'UNDEFINED'; } if (typeof item === 'string' || item instanceof String) { return `${item}`; } return item.toString(); } class ValuePair { constructor(key, value) { this.key = key; this.value = value; } toString() { return `[#${this.key}: ${this.value}]`; } } class Dictionary { constructor(toStrFn = defaultToString) { this.toStrFn = toStrFn; this.table = {}; } set(key, value) { if (key != null && value != null) { const tableKey = this.toStrFn(key); this.table[tableKey] = new ValuePair(key, value); return true; } return false; } get(key) { const valuePair = this.table[this.toStrFn(key)]; return valuePair == null ? undefined : valuePair.value; } hasKey(key) { return this.table[this.toStrFn(key)] != null; } remove(key) { if (this.hasKey(key)) { delete this.table[this.toStrFn(key)]; return true; } return false; } values() { return this.keyValues().map(valuePair => valuePair.value); } keys() { return this.keyValues().map(valuePair => valuePair.key); } keyValues() { return Object.values(this.table); } forEach(callbackFn) { const valuePairs = this.keyValues(); for (let i = 0; i < valuePairs.length; i++) { const result = callbackFn(valuePairs[i].key, valuePairs[i].value); if (result === false) { break; } } } isEmpty() { return this.size() === 0; } size() { return Object.keys(this.table).length; } clear() { this.table = {}; } toString() { if (this.isEmpty()) { return ''; } const valuePairs = this.keyValues(); let objString = `${valuePairs[0].toString()}`; for (let i = 1; i < valuePairs.length; i++) { objString = `${objString},${valuePairs[i].toString()}`; } return objString; } } ~~~