4

I'm trying to figure this javascript variable referencing issue out. Here is a fiddle to demonstrate what I'm about to explain: http://jsfiddle.net/XpVb5/1/

I have an object that I want to define and call within a separate object's properties.

var vals = {'something':1};  //original object
var buf  = {'field1': vals, 'field2': vals};  //second object with original object used as properties

Now I want to change the something property for only field1, so naturally, I would do this:

buf.field1.something = 0;

However, this will also change field2's something property. I'm assuming that this is because of how Javascript references variables in the variable definition process. But, in either case, how can I get around this without explicitly calling {'something':0} each time I need to use it in a property definition; like so:

var buf = {'field1': {'something':0}, 'field2': {'something':1}};
sadmicrowave
  • 39,964
  • 34
  • 108
  • 180
  • This is more of a by-value/by-reference question than a scoping one. See, e.g. http://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language – Scott Mermelstein Nov 12 '13 at 22:22

2 Answers2

3

You need to create a copy of the vals object. Currently you're just providing a reference to the object in both places. When you modify the base object, the change appears in both buf's (field1 + field2) because they only provide a reference to the base object.

Note: I'm using JSON.parse(JSON.stringify($vals)) as a quick example on how to copy the $vals object.

var $vals   = {"something":1},
    buf     = {"field1": JSON.parse(JSON.stringify($vals)), "field2": JSON.parse(JSON.stringify($vals))};

//change the 'something' field for one of the buf properties
buf.field1.something = 0;

//see if the 'something' field changed for the other buf property
alert( buf.field2.something );

http://jsfiddle.net/XpVb5/2/

Gives

1

Further reading: "The most elegant way to clone an object"

Community
  • 1
  • 1
Nick Grealy
  • 24,216
  • 9
  • 104
  • 119
  • What if my object was a jquery DOM object? Wouldn't that break? – sadmicrowave Nov 12 '13 at 22:25
  • At the end of the day, if you want to update two separate objects independently, you'll need to have two separate instances of your object. How you get two instances is up to you! – Nick Grealy Nov 12 '13 at 22:27
1

Can change $vals to a function that returns an object. Each return will be a different instance

var $vals = function(){
    return {"something":1}
}
var  buf     = {"field1": $vals(), "field2": $vals()};

//change the 'something' field for one of the buf properties
buf.field1.something = 0;

//see if the 'something' field changed for the other buf property
alert( buf.field2.something );

DEMO

charlietfl
  • 170,828
  • 13
  • 121
  • 150