views:

686

answers:

5

I've realized you can have a property in an object run automatically like this:

var obj = {

    init:(function(){ alert('loaded');})();

}

I'm trying to use this method as an initializer for the object. The problem I'm running into is passing a reference to 'obj' to the init property. I suspect it generates errors because the obj hasn't been completely built in browser yet. I'm trying to do the following, but unsuccessfully. If there's a way to do this, I'd love to know how.

var obj = {
    prop:function(){ alert('This just ran.'); },
    init:(function(){ obj.prop(); })();
}
A: 

Does it work if you pass "this" into the init function?

something like: (untested)

var obj = {
    prop:function(){ alert('This just ran.'); },
    init:(function(o){ o.prop(); })(this);
}
Andrew Bullock
Nah. Passing (this) is a reference to window.object
Geuis
A: 

I think you want to try something like this:

var obj = {
    prop: function() { alert('This just ran.'); },
    init: function() { obj.prop(); }
}

Object literals reqire comma-separated members without semicolons.

Andrew Hare
that wont run the init function on creation though
Andrew Bullock
You are right - there isn't any way to do that with object literals.
Andrew Hare
+2  A: 

This is not possible: obj doesn't exist until the whole block is interpreted.

Maurice Perry
+2  A: 

Why don't you use the contructor model (actually, I have no idea of its correct name):

function Obj() {
    // Initialising code goes here:
    alert( 'Loaded!' );

    // ...

    // Private properties/methods:
    var message = 'hello',
        sayHello = function() {
            alert(message);
        };

    // Public properties/methods:
    this.prop = function() {
        sayHello();
    };

    // Encapsulation:
    this.setMessage = function(newMessage) {
        message = newMessage;
    };
}

Usage:

var instance = new Obj();
instance.setMessage('Boo');
instance.prop();
J-P
A reason for not initialising in the constructor is that you need to call the constructor every time you want a prototype (eg. to make a subclass) — function XObj() {...}; XObj.prototype= new Obj();. You don't really want to initialise an actual instance in this case.
bobince
+2  A: 

If you want to create multiple instances of similar objects, you should use plain old constructor functions (remember to put shared properties in the prototype!).

If you want to create a single object, consider using an anonymous constructor. Your example would read:

var obj = new (function() {
    this.prop = function() {
        alert('This just ran.');
    }

    // init code goes here:
    this.prop();
});

This has an additional benefit over object literals: the constructor function can be used as a closure over 'private' variables.

Don't overuse object literals: they may make simple things simple, but complex things will get overly complicated.

Christoph