2012-06-26 116 views
7

我使用一個特定的遊戲製作框架,但我認爲這個問題適用於JavaScript的的Javascript對象推到數組改變整個陣列

我試圖讓旁白腳本,以便玩家可以看到「獸人打你「。在他的屏幕底部。我想一次顯示最後4條消息,並且可能允許玩家回頭看他們想要的日誌中的30-50條消息。爲此,我設置了對象和一個數組來將對象推入。

所以我設置了一些變量像這樣一開始...

servermessage: {"color1":"yellow", "color2":"white", "message1":"", "message2":""}, 
servermessagelist: new Array(), 

,當我通過操縱servermessage.color1 ...使用此命令(下圖)多次通過一個事件稱爲不同的數據。 message1等...

servermessagelist.push(servermessage) 

它覆蓋整個數組與該數據的副本......任何想法爲什麼或我能做些什麼。

因此,如果我推color1「RED」和message1「Rover」..數據是正確的,那麼如果我按 color1「yellow」和message1「Bus」,數據是.color1:「yellow」的兩個副本。 message1:「總線」

+0

你是什麼意思「用整個數據的副本覆蓋整個陣列」?你可以顯示你用來迭代結果數組的代碼嗎? –

回答

16

當您將servermessage推入servermessagelist時,您確實(或多或少)推送對該對象的引用。因此,對servermessage所做的任何更改都會反映到您有任何參考的地方。這聽起來像你想要做的是將對象的克隆推入列表中。

聲明函數如下:

function cloneMessage(servermessage) { 
    var clone ={}; 
    for(var key in servermessage){ 
     if(servermessage.hasOwnProperty(key)) //ensure not adding inherited props 
      clone[key]=servermessage[key]; 
    } 
    return clone; 
} 

然後每次要推一個消息到列表做:

servermessagelist.push(cloneMessage(servermessage)); 
+0

有沒有一種更簡單的方法,我可以通過聲明一個對象數組來做到這一點?我不知道該怎麼做。 – Shawn

+0

每次要推送'servermessage'時,您都必須進行克隆。一旦你改變它,克隆它,然後推它的克隆。 – nbrooks

+0

那麼您可以每次使用第一個對象的屬性聲明一個新對象,並將值設置爲'null'或'' – nbrooks

1

servermessagelist:new Array()每次執行數組時清空數組。最初初始化數組時,只能執行一次該代碼。

+0

消息列表是在我的初始功能推送是在一個websocket事件上運行的更新功能... – Shawn

+0

啊,我的壞,我沒有得到你的代碼示例。但正如nbrooks所說,在javascript對象中總是作爲參考傳遞,這就是它無法正常工作的原因。 – riku

2

當你的對象添加到陣列,它只是一個參考到添加的對象。該對象不會通過將其添加到數組而被複制。因此,當您稍後更改對象並再次將其添加到數組時,您只需擁有一個對同一對象具有多個引用的數組。

每個除數組創建一個新的對象:

servermessage = {"color1":"yellow", "color2":"white", "message1":"", "message2":""}; 
servermessagelist.push(servermessage); 
servermessage = {"color1":"green", "color2":"red", "message1":"", "message2":"nice work"}; 
servermessagelist.push(servermessage); 
0

我也有同樣的問題。我有點複雜的對象,我正在推入陣列。我做了什麼;我使用JSON.stringify()將JSON對象轉換爲字符串並將其推入數組。

當它從數組返回時,我只是使用JSON.parse()將該String轉換爲JSON對象。

這對我來說工作得很好,雖然它有點遠爲圓解。 這裏發佈如果你們有其他選擇