鍍金池/ 問答/HTML/ 如何用Object實現(xiàn)Map數(shù)據(jù)結(jié)構(gòu)

如何用Object實現(xiàn)Map數(shù)據(jù)結(jié)構(gòu)

如題。map數(shù)據(jù)結(jié)構(gòu)和object有一個區(qū)別是Map可以將任意類型值作為key,例如對象,函數(shù)。
請問用ES5的對象該如何實現(xiàn)?

回答
編輯回答
命于你

https://github.com/hprose/hpr...

這里有實現(xiàn)。

2017年7月28日 19:50
編輯回答
心悲涼

proxy getter

2017年7月29日 18:44
編輯回答
青瓷
let Map = () => {
    let values = [];
    let find_index = (key) => {
        let result = values.filter(item => item.key === key);
        return result.length === 0 ? -1 : result[0].id;
    }
    
    return {
        set: (key, value) => {
            let index = find_index(key);
            if (index === -1) {
                values.push({id: values.length, key: key, value: value});
            } else {
                values[index].value = value;
            }
            return value;
        },
        
        get: (key, value) => {
            value = value === undefined ? null : value;
            let index = find_index(key);
            return index === -1 ? value : values[index].value;
        }
    }
}

測試:

let map = Map();
let obj_key = {a: 1, b: 2};
let func_key = () => {};

map.get(0);            // null
map.get(0, 0);         // 0

map.set('1', 1);       // 1
map.get('1');          // 1
map.set('1', () => {}) // () => {}

map.set(obj_key, 1);   // 1
map.get(obj_key);      // 1

map.set(func_key, 1);  // 1
map.get(func_key);     // 1

不知道這樣行不行?順手做了 get_or_default 的效果。

2018年3月15日 21:01
編輯回答
近義詞
function reDefineValueOf(key) {
  const private = {};
  const baseValueOf = key.valueOf;
  function valueOf(n) {
    if (arguments.length > 0) {
      if (!(n in private)) {
        private[n] = {};
      }
      return private[n];
    }
    return baseValueOf.apply(this, arguments)
  }
  Object.defineProperty(key, 'valueOf', {
    value: valueOf,
    configurable: true,
    writable: true,
    enumerable: false
  })

}

function map() {
  //通過count來解決,不同map對象,用相同對象作key的情況
  const count = map.count++;
  function getKey(key) {
    if (key.valueOf.length !== 0) {
      return key.valueOf(count)
    }
    reDefineValueOf(key)
    return key.valueOf(count);
  }
  this.get = function (key) {
    return getKey(key).value;
  }
  this.set = function (key, value) {
    getKey(key).value = value;
  }
}
map.count = 0;
var c = { c: 1 }
var a = new map();
var b = new map();
a.set(c, 'a')
b.set(c, 'b')

console.log(a.get(c));
console.log(b.get(c));

通過樓上答案提供的代碼,這里寫了一個簡單版本。
核心思想是,既然key是對象,那么就給key對象新增一個函數(shù),這個函數(shù)返回的值就是我們當時設置的值。然而由于可能出現(xiàn)不同的map對象,用相同的對象作key值的情況,這里給每一個map對象加了一個count計數(shù)器,用來作為map對象的id,以此作為key對象查找的一個依據(jù)。

2018年1月9日 04:59