2010-11-22 66 views
168
一個簡單的地圖

你怎麼能創建的JavaScript/JQuery的相當於這個Java代碼:如何創建使用JavaScript/JQuery的

Map map = new HashMap(); //Doesn't not have to be a hash map, any key/value map is fine 
map.put(myKey1, myObj1); 
map.put(myKey2, myObj2); //Repeat n times 

function Object get(k) { 
    return map.get(k); 
} 

回答

263

編輯:過時的答案,ECMAScript的2015年(ES6)標準JavaScript有Map實現,讀到這裏更多的信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

var map = new Object(); // or var map = {}; 
map[myKey1] = myObj1; 
map[myKey2] = myObj2; 

function get(k) { 
    return map[k]; 
} 

//map[myKey1] == get(myKey1); 
+10

更新了我的答案,使用`new Object()`而不是`new Array()`。請參閱[本文](http://andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/) – 2010-11-22 15:55:10

+0

我們如何在這裏提供根節點? – Krishnan 2011-06-15 20:28:38

+0

我們如何從地圖中移除關鍵值付款人? – 2013-01-29 05:37:33

60

只需使用普通的對象:

var map = { key1: "value1", key2: "value2" } 
function get(k){ 
    return map[k]; 
} 
13
var map = {'myKey1':myObj1, 'mykey2':myObj2}; 
// You don't need any get function, just use 
map['mykey1'] 
6

如果您不受限於JQuery,則可以使用prototype.js框架。它有一個名爲Hash的類:你甚至可以一起使用JQuery & prototype.js。只需鍵入jQuery.noConflict();

var h = new Hash(); 
h.set("key", "value"); 
h.get("key"); 
h.keys(); // returns an array of keys 
h.values(); // returns an array of values 
23
function Map() { 
    this.keys = new Array(); 
    this.data = new Object(); 

    this.put = function (key, value) { 
     if (this.data[key] == null) { 
      this.keys.push(key); 
     } 
     this.data[key] = value; 
    }; 

    this.get = function (key) { 
     return this.data[key]; 
    }; 

    this.remove = function (key) { 
     this.keys.remove(key); 
     this.data[key] = null; 
    }; 

    this.each = function (fn) { 
     if (typeof fn != 'function') { 
      return; 
     } 
     var len = this.keys.length; 
     for (var i = 0; i < len; i++) { 
      var k = this.keys[i]; 
      fn(k, this.data[k], i); 
     } 
    }; 

    this.entrys = function() { 
     var len = this.keys.length; 
     var entrys = new Array(len); 
     for (var i = 0; i < len; i++) { 
      entrys[i] = { 
       key: this.keys[i], 
       value: this.data[i] 
      }; 
     } 
     return entrys; 
    }; 

    this.isEmpty = function() { 
     return this.keys.length == 0; 
    }; 

    this.size = function() { 
     return this.keys.length; 
    }; 
} 
18

這是一個老問題,但因爲現有的答案是很危險的,我想離開這個答案誰可能絆倒這裏未來的鄉親...

的基於使用Object作爲HashMap的答案被破壞,並且如果您使用除String之外的其他任何內容作爲關鍵字,則會導致極其惡劣的後果。問題是Object屬性使用.toString方法強制轉換爲Strings。這可能會導致以下污穢:

function MyObject(name) { 
    this.name = name; 
}; 
var key1 = new MyObject("one"); 
var key2 = new MyObject("two"); 

var map = {}; 
map[key1] = 1; 
map[key2] = 2; 

如果你期待的是對象竟然能做出同樣的方式作爲一個Java地圖在這裏,你會相當惱火地發現,地圖僅包含一個條目以字符串鍵[object Object]

> JSON.stringify(map); 
{"[object Object]": 2} 

這顯然是不 Java的HashMap中的替代品。奇怪的是,鑑於它的年齡,Javascript目前沒有通用的地圖對象。儘管如此,儘管如此,瀏覽器兼容性表中的一覽表顯示,這還未準備好用於通用Web應用程序。

在此期間,你能做的最好的是:

  • 故意用字符串作爲鍵。即使用明確的字符串作爲鍵,而不是依賴所使用的鍵的隱式.toString。
  • 確保您用作鍵的對象有一個定義良好的.toString()方法,它適合您理解這些對象的唯一性。
  • 如果您不能/不想更改關鍵對象的.toString,當存儲和檢索條目時,將對象轉換爲表示您對唯一性的理解的字符串。例如。 map[toUniqueString(key1)] = 1

雖然有時候這是不可能的。如果要基於File對象映射數據,則沒有可靠的方法來執行此操作,因爲File對象公開的屬性不足以確保其唯一性。 (您可能有兩個File對象代表磁盤上的不同文件,但在瀏覽器中無法在JS中區分它們)。不幸的是,在這些情況下,你所能做的只是重構你的代碼以消除將這些存儲在may中的需要;也許,通過使用一個數組來代替它們並且僅僅通過索引來引用它們。