0

I wrote a simple test script in fiddle: http://jsfiddle.net/resting/qfCue/

What I'm trying to do is to set the margin property as 2, and let obj.foptions.labelMargin and obj.marginClone take in this value.

I know its possible to change in value in obj.foptions.labelMargin and obj.marginClone directly. But that wouldn't allow me to "change one place, change in all places".

Instead, both obj.foptions.labelMargin and obj.marginClone are undefined.
How do I get this.margin to read as 2?

Code:

var obj= {
    margin: 10,
    setMargin: function(val) { this.margin = val; },
    foptions: { labelMargin: this.margin },
    marginClone: this.margin
}

obj.setMargin(2);
console.dir(obj.foptions);
console.log(obj.marginClone);
console.log(obj.margin);
resting
  • 16,287
  • 16
  • 59
  • 90

1 Answers1

0

The typical way to do this in JavaScript is to use a function to create a scope that holds state. Here's what your code would look like rewritten in that style:

function obj()
{
    var that = this;

    that.margin = 10;
    that.setMargin = function(val) { 
        that.margin = val; 
    };
    that.foptions = { 
        labelMargin: that.margin 
    };
    that.marginClone = that.margin;
}

var inst = new obj();
inst.setMargin(2);
console.dir(inst.foptions);
console.log(inst.marginClone);
console.log(inst.margin);

See it on JSFiddle.

With respect to marginClone, recall that JavaScript has reference semantics only for object types--so for scalar values, you'll always be making a copy. You can wrap the scalar in an object if you want it to be pass-by-reference.

Jonathan
  • 8,497
  • 41
  • 35
  • There's no need for the `that` closure, and no need to use inheritance with `new`. – Bergi Aug 08 '13 at 17:00
  • It's true that `that` is unnecessary here. I use it out of habit because you can't rely on `this` being set to the instance (e.g. when the method is invoked from an event handler), and it's easier to always use the closure than to work out what might somehow get invoked from an event handler in the future. – Jonathan Aug 09 '13 at 21:28
  • @Jonathan Thanks for solution. But when I ran the code, it shows `inst.foptions.labelMargin` and `inst.marginClone` as 10. I was assuming it should had been set as 2 by `inst.setMargin(2)`? – resting Aug 09 '13 at 22:56
  • In this example setMargin changes only `margin`, not `marginClone`, since there's no code to keep those things in sync. If you wanted to keep those in sync, you could do so by either by creating `margin` as an object (to get reference semantics), or by setting `marginClone` inside `setMargin`. – Jonathan Aug 12 '13 at 19:36