1

Lets say I have an object generated from an xml document it is very deep, so I can reach a value like:

myobject.really[0].long.chain[43].to.travel.to.get.my[5].desired.$.value

If I want to update this property based on it's previous value then I could do it like this:

myobject.really[0].long.chain[43].to.travel.to.get.my[5].desired.$.value = 
updateFn(
  myobject.really[0].long.chain[43].to.travel.to.get.my[5].desired.$.value,
  otherparam1, otherparam2);

This makes my code very hard to read, is there any nice solution to pass a parameter as a reference not by value?

So then my code could look like this:

updateFn(ref, param1, param2) {
  // "ref =" act as a reference, "(ref)" act as a value
  ref = someThingToDoWithTheOldValue(ref);
}

Call it like this:

updateFn(
  myobject.really[0].long.chain[43].to.travel.to.get.my[5].desired.$.value,
  otherparam1, otherparam2);
// So I can omit the myobject.really[0].long.chain[43].to.travel.to.get.my[5].desired.$.value =  part
micnic
  • 10,168
  • 5
  • 41
  • 53
NoNameProvided
  • 7,954
  • 9
  • 37
  • 63
  • 4
    `var o = myobject.really[0].long.chain[43].to.travel.to.get.my[5].desired.$` then `o.value = whatever`. – RobG Jun 29 '15 at 11:11
  • if I do that, then I only have the `$` object in the 'o' variable, but I need the whole stuff later. – NoNameProvided Jun 29 '15 at 11:15
  • 1
    And you'd still have "the whole stuff" later accessible via the full chain of properties from `myobject`, in addition to having the `o` variable that is a direct reference to the `...$` object. – nnnnnn Jun 29 '15 at 11:19
  • 1
    Related: [Is JavaScript a pass-by-reference or pass-by-value language?](http://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language) – laggingreflex Jun 29 '15 at 11:29

2 Answers2

2

You can assign a variable name to any deep down properties.

var desired_$ = myobject.really[0].long.chain[43].to.travel.to.get.my[5].desired.$

Any changes made to desired_$ will actually reflect on myobject.really...desired.$

desired_$.value = updateFn( desired_$.value, otherparam1, otherparam2);

You can pass myobject around and myobject.really...desired.$.value would still be what you set through desired_$.value above.


Does this mean if I pass the 'myobject.really[0].long.chain[43].to.travel.to.get.my[5].desired.$' as a paramter in the function, then it will reflect the canges on the original object too?

It depends on what you actually do with it. Here' the general rule: If you change a property on an object, the object stays the same - i.e. you can pass that object and its property that you changed will hold the value that you changed it to.

For example:

var obj = { outer: { inner: {prop: 1} } };

I have three function that change the properties in following ways:

function changeProp(prop){
    prop = 2;
}
function changeInner(inner){
    inner.prop = 2;
}
function changeInnerCompletely(inner){
    inner = 2;
}

Then their respective effects would be as such:

changeProp(obj.outer.inner.prop);
obj.outer.inner.prop //=> 1   // original unchanged

changeInner(obj.outer.inner);
obj.outer.inner.prop //=> 2   // original changed!

changeInnerCompletely(obj.outer.inner);
obj.outer.inner //=> 2        // original 'inner' itself changed

So as long as you change the child property on an object, the original object reflects the changes. But if you change the object entirely then the "reference" is broken and original object and the one you passed to the function are now two separate entities.

laggingreflex
  • 29,919
  • 31
  • 129
  • 183
  • Does this mean if I pass the `myobject.really[0].long.chain[43].to.travel.to.get.my[5].desired.$` as a paramter in the function, then it will reflect the canges on the original object too? – NoNameProvided Jun 29 '15 at 11:29
0

you could do something like

    function setProp(ref, prop, val)
    {
           ref[prop] = val;
    }

    ...
      setProp(myobject.really[0].long.chain[43].to.travel.to.get.my[5].desired.$, "value", "new Value");

but I doubt that this makes your code more readable anyhow ...

IDEA

add a generic setter to each object:

    Object.prototype.setProp = function(prop, val)
    {
           this[prop] = val;
    }

and then:

myobject.really[0].long.chain[43].to.travel.to.get.my[5].desired.$.setProp("value", "new Value");

small fiddle here

Axel Amthor
  • 10,816
  • 1
  • 24
  • 44