2017-07-02 48 views
0

我正在使用地圖訪問類似於普通對象的JavaScript地圖

因爲我想存儲一個對象作爲關鍵。

我的問題是 - 我可以像訪問普通對象一樣訪問地圖嗎?

例如:

let m = new Map(); 
let obj = {foo:'bar'}; 
m[obj] = 'baz'; 
console.log(m[obj]); 

被這個所謂的正確的是工作,還是我需要使用地圖的get/set方法?

我問的原因是因爲如果我需要使用get/set它強制我仔細重構很多代碼。

這裏是代碼,可能需要重構一個實際的例子:

//之前(broker.wsLock是普通對象)

function addWsLockKey(broker, ws, key) { 
    let v; 
    if (!(v = broker.wsLock[ws])) { 
    v = broker.wsLock[ws] = []; 
    } 
    if (v.indexOf(key) < 0) { 
    v.push(key); 
    } 
} 

//後(經紀人。 wsLock是一個地圖實例)

function addWsLockKey(broker, ws, key) { 
    let v; 
    if (!(v = broker.wsLock.get(ws))) { 
    v = []; 
    broker.wsLock.set(ws, v); 
    } 
    if (v.indexOf(key) < 0) { 
    v.push(key); 
    } 
} 

是有一些方法來設置在同一行的集合v()C所有?

+3

a地圖就像任何其他的JS對象一樣,所以你可以像你一樣添加屬性,但是你正在做的是添加一個屬性''[object object]'' - 而不是添加一個實際的地圖條目。換句話說,你需要使用set/get –

+0

我只是在控制檯上試過你的例子 - 它似乎工作正常。 – Zac

+1

@Zac,它只顯示工作,該值實際上沒有分配給實際對象表示的屬性,而是被設置爲Jaromanda X提到的名爲'[object Object]'的屬性。 –

回答

2

如果你想訪問Map對象的實際值,那麼你必須使用.get().set()或各種迭代器。在Map

var m = new Map(); 
m.set("test", "foo"); 
console.log(m.get("test")); // "foo" 

定期訪問屬性:

m["test"] = "foo" 

僅設置對象的正規屬性 - 它不會影響實際的地圖數據結構。

我想它是這樣完成的,以便您可以訪問與Map數據結構的成員分開的Map對象屬性,並且兩者不得相互混淆。


此外,常規屬性只接受字符串作爲屬性名稱,因此您不能使用常規屬性來索引對象。但是,使用.set().get()時,地圖對象具有該功能。


您要求「明確」的答案。在ES6 specification中,您可以查看.set()所做的操作,並看到它在[[MapData]]內部插槽上運行,這當然與對象的屬性不同。而且,同樣地,在該規範中沒有說使用普通屬性訪問會訪問內部對象[[MapData]]。所以,你必須看到正常的屬性訪問被描述爲一個對象。 A MapObject,並且Map規範中沒有任何內容說明普通屬性訪問的行爲與任何其他對象的行爲不同。實際上,對於Map對象上的所有方法,它們必須採用相同的操作,否則,如果碰巧使用與方法名稱相同的密鑰將項目放在Map中,它們將不起作用。所以,你證明了這一點:

  1. 一個簡單的測試會告訴你,屬性訪問不會把任何東西放在Map本身,只有一個常規的屬性。
  2. 該規範將Map描述爲一個對象。
  3. 該規範描述了.get().set()如何在內部插槽[[MapData]]上運行。
  4. 規範中沒有任何內容說明Map對象的屬性訪問應該與以往不同。
  5. 如果屬性訪問沒有訪問MapData,那麼如果碰巧在與方法名稱衝突的Map中輸入密鑰,那麼您將無法訪問方法 - 如果情況如此,那將是一團糟。
+0

明白了,這很有道理 – Olegzandr

+0

是的,我需要使用map的原因是,我可以使用一個對象作爲關鍵。謝謝(你的)信息。 – Olegzandr

+0

但是,我正在尋找這種便利: – Olegzandr