Question

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(); })();
}
Was it helpful?

Solution

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.

OTHER TIPS

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

A simple alternative:

var obj = {

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

}.init();

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();

Yes, obj does not seem to exist locally till later. This worked for me with setTimeout. Tested ok on IE8, FF5, Chrome 12, Opera v11.5. Not sure about the 50 milliseconds though, I imagine it is enough.

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

this is an update to the example submitted by user1575313.

the original code works but it limits the use of the object after setup. By returning the object reference in the init method it allows the object to be used outside the object.

link to jsFiddle. jsFiddle

var obj = {

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

    this.consoleLog(); 

    /* we want to return this to keep object 
    usable after auto init */ 
    return this;
}, 

consoleLog: function() 
{
    console.log(1); 
}

}.init(); 

/* the obj should now be usable outside the auto init */ 
obj.consoleLog();

Init in jQuery-like style

(function() {

var $ = function(){
  return new $.fn.init();
};

$.fn = $.prototype = {
  init: function(){ 
    this.prop(); 
  },
  i: 0,
  prop: function(){ 
    alert('This just ran. Count: ' + (++this.i)); 
    return this;
  }
};

$.fn.init.prototype = $.fn;

$().prop().prop();

})();

jsbin.com

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.

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);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top