tags:

views:

50

answers:

4

Objects in javascript throw me for a loop!

In this set up...

var obj = {
    someVar: "my awesome variable",
    foo: {
        bar: function(){
            alert(this.someVar);
        }
    }
};

How would I get obj.foo.bar to correctly alert the value of someVar?

+1  A: 

Using a captured obj:

var obj = {
    someVar: "my awesome variable",
    foo: {
        bar: function(){
            alert(obj.someVar);
        }
    }
};
spender
This works great for me, and that's all I really need.Just wondering though, I'm only using the object as a wrapper for collecting functions that were getting out of hand and this is really my first attempt at organizing obj.properties to be used later.Is this the same method something like jQuery uses to reference the main obj's properties or is this only going to work with... static(?) objects?
bschaeffer
Please note that this is only possible because it is an object literal. The same is not true for instantiated objects (unless that object is a singleton).
Justin Johnson
+1  A: 
alert(obj.someVar);

There's no clever way to walk up the ancestor chain. Objects don't know where they're contained, if you're looking for some type of this.parent type of notation. There's nothing to say that an object even has a single "parent".

foo.foo = new Object();
bar.bar = foo.foo;

bar.bar.parent == ???
John Kugelman
+1  A: 

A function in Javascript is invoked only in the context of the object which the . operator was applied to. It is not possible to walk up the chain, since Javascript objects are not intrinsically aware of their parent objects.

The only way to do this is to have a separate reference to obj. (Either as a property of bar or a separate variable)

SLaks
That is just not true. Since `obj` is an object literal, it can be referred to by name (as shown by spender)
Justin Johnson
@Justin: I realize that. However, the variable might be reassigned.
SLaks
+1  A: 

Here's a generalized pattern I just cooked up for upwards traversal. Depending on your needs/assumptions, you can probably drop some complexity.

var obj = (function (parent) {
    var obj = {
        foo: "foo",
        up: function () {
            return parent;
        }
    };

    obj.bar = (function (parent) {
        var obj = {             
            baz: function () {
                alert(this.up().foo);
            },
            up: function () {
                return parent;
            }
        };

        return obj;
    }(obj));

    return obj;
}(window));

obj.bar.baz(); // "foo"

It's almost certainly more trouble than it's worth.

bcherry