2014-05-12 25 views
5

令我驚訝的是,這個代碼實際工作中的Node.js:node.js數組實際上hashmaps?

var arr = new Array(); 
// also works: var arr = []; 
arr[0] = 123; 
arr['abc'] = 456; 
arr; // node.js: [ 123, abc: 456 ], chrome: [123] 

我一直認爲,一個陣列中存儲其順序的對象,僅通過一個整數鍵訪問,就像一個std ::向量C++。但是,在這裏它就像一張地圖或一個物體。再加上混淆,相同的代碼在chrome中按預期工作,並返回一個帶有單個條目123的數組。我認爲node.js和chrome javascript使用相同的內部引擎V8。這裏發生了什麼?

+0

不,他們實際上是JavaScript數組,其中有一種「對象」! – adeneo

+2

儘管chrome在控制檯中不顯示'456',但arr.abc仍然是'456'。它只是不顯示它在控制檯,除非你明確地訪問變量,或'console.log(arr)',它記錄:'[123,abc:456]'基本上,這只是一個整容問題。 – Cerbrus

+0

如果它存儲在'abc'下面,那不是一個散列圖。只是一個鍵/值數組。 –

回答

7

Javascript允許您在運行時擴展對象,並且作爲Array是您可以這樣做的對象。

你正在做的是給你的數組添加一個新的屬性,名爲abc,併爲其分配值456

所以你可以說Javascript中的每個對象都可以用作hashmap。

EDIT

看來,鉻在傾倒而轉儲節點每一個用戶定義的屬性過濾Array對象的非數字屬性。在我看來節點的方式是更好,因爲字母數字財產的for in聲明可供選擇:

var a = [1]; 
a['abc'] = 2; 
for (var i in a) { 
    console.log(i); 
} 
// Prints: 
// 0 
// abc 
+0

是的,每個對象都可以用作散列表,但這不是問題。這只是顯示變量時的不一致。這就是爲什麼我還原編輯,也是:這個「問題」實際上是特定於node.js – Cerbrus

+0

@Cerbrus在我看來,問題的關鍵並不是通過'console.log()'顯示或不顯示,而是數組/對象在Javascript中的行爲。 – Carlos

+0

你仍然沒有解決這樣一個事實,即在節點和chrome中行爲似乎不同,事實上對象包含相同的鍵/值對。 – Cerbrus

2

雖然Chrome瀏覽器不會顯示在控制檯456當你剛進入arrarr.abc仍將456

它只是不顯示它在控制檯,除非你明確地訪問變量,或console.log(arr),其中記錄:[123, abc: 456]

基本上,這只是一個整容問題。當你在控制檯中輸入變量時,Node.js確實顯示了數組對象的鍵/值屬性,而chrome只顯示「正常」數組條目,即使兩個數組實際上具有相同的內容。

+0

@Joel:這是回答你的問題,還是還不清楚? – Cerbrus

5

答案是對的,如果您嘗試顯示長度爲的數組,則行爲可能更容易理解。

var ar = [] 
ar[0] = 42 
console.log(ar.length) // 1 

ar[12] = 21 
console.log(ar.length) // 13 

ar['ab'] = 1 
console.log(ar.length) // 13 (separate property, not in array) 

ar[ar.length] = 33 
console.log(ar.length) // 14 

ar.push(55) 
console.log(ar.length) // 15 

console.log(ar) // display all items specified above 
//[ 42, , , , , , , , , , , , 21, 33, 55, ab: 1 ] 
// which in fact really is: 
// [ 42, , , , , , , , , , , , 21, 33, 55] as array and 
// special property of array object - 'ab':1