Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript pushing objects into array changes entire array

I'm using a specific game making framework but I think the question applies to javascript

I was trying to make a narration script so the player can see "The orc hits you." at the bottom of his screen. I wanted to show the last 4 messages at one time and possibly allow the player to look back to see 30-50 messages in a log if they want. To do this I set up and object and an array to push the objects into.

So I set up some variables like this initially...

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

and when I use this command (below) multiple times with different data called by an event by manipulating servermessage.color1 ... .message1 etc...

servermessagelist.push(servermessage)

it overwrites the entire array with copies of that data... any idea why or what I can do about it.

So if I push color1 "RED" and message1 "Rover".. the data is correct then if I push color1"yellow" and message1 "Bus" the data is two copies of .color1:"yellow" .message1:"Bus"

like image 936
Shawn Avatar asked Jun 26 '12 23:06

Shawn


People also ask

Does push change array?

The push() method adds new items to the end of an array. The push() method changes the length of the array.

Why does changing an array in JavaScript affect copies of the array?

An array in JavaScript is also an object and variables only hold a reference to an object, not the object itself. Thus both variables have a reference to the same object.

Can you push an object into an array JavaScript?

The push() method is used to add one or multiple elements to the end of an array. It returns the new length of the array formed. An object can be inserted by passing the object as a parameter to this method. The object is hence added to the end of the array.

Can you push an array into an array JavaScript?

push. apply(newArray, dataArray2); As "push" takes a variable number of arguments, you can use the apply method of the push function to push all of the elements of another array. It constructs a call to push using its first argument ("newArray" here) as "this" and the elements of the array as the remaining arguments.


2 Answers

There are two ways to use deep copy the object before pushing it into the array. 1. create new object by object method and then push it.

servermessagelist = []; 
servermessagelist.push(Object.assign({}, servermessage));
  1. Create an new reference of object by JSON stringigy method and push it with parse method.

    servermessagelist = []; servermessagelist.push(JSON.parse(JSON.stringify(servermessage));

This method is useful for nested objects.

like image 109
Vaibhav Lokhande Avatar answered Oct 20 '22 01:10

Vaibhav Lokhande


When you push servermessage into servermessagelist you're really (more or less) pushing a reference to that object. So any changes made to servermessage are reflected everywhere you have a reference to it. It sounds like what you want to do is push a clone of the object into the list.

Declare a function as follows:

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;
}

Then everytime you want to push a message into the list do:

servermessagelist.push( cloneMessage(servermessage) );
like image 27
nbrooks Avatar answered Oct 19 '22 23:10

nbrooks