Pregunta

Me he dado cuenta de que puedes tener una propiedad en un objeto que se ejecuta automáticamente de esta manera:

var obj = {

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

}

Estoy tratando de usar este método como un inicializador para el objeto. El problema que estoy encontrando es pasar una referencia a 'obj' a la propiedad init. Sospecho que genera errores porque el objeto todavía no se ha construido completamente en el navegador. Estoy tratando de hacer lo siguiente, pero sin éxito. Si hay una manera de hacer esto, me encantaría saber cómo.

var obj = {
    prop:function(){ alert('This just ran.'); },
    init:(function(){ obj.prop(); })();
}
¿Fue útil?

Solución

Si desea crear múltiples instancias de objetos similares, debe usar funciones de constructor antiguas (¡recuerde poner propiedades compartidas en el prototipo!).

Si desea crear un solo objeto, considere usar un constructor anónimo. Tu ejemplo diría:

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

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

Esto tiene un beneficio adicional sobre los literales de objetos: la función constructora se puede usar como un cierre sobre variables 'privadas'.

No abuses de los objetos literales: pueden hacer que las cosas simples sean simples, pero las cosas complejas se complicarán demasiado.

Otros consejos

Esto no es posible: el objeto no existe hasta que se interpreta todo el bloque.

Una alternativa simple:

var obj = {

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

}.init();

¿Por qué no usas el modelo de constructor (en realidad, no tengo idea de su nombre correcto):

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;
    };
}

Uso:

var instance = new Obj();
instance.setMessage('Boo');
instance.prop();

Sí, obj no parece existir localmente hasta más tarde. Esto me funcionó con setTimeout . Probado bien en IE8, FF5, Chrome 12, Opera v11.5. Aunque no estoy seguro de los 50 milisegundos, imagino que es suficiente.

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

esta es una actualización del ejemplo enviado por el usuario1575313.

el código original funciona pero limita el uso del objeto después de la configuración. Al devolver la referencia del objeto en el método init, permite que el objeto se use fuera del objeto.

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

Inicial en estilo de jQuery

(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

Creo que quieres probar algo como esto:

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

Los literales de objetos requieren miembros separados por comas sin punto y coma.

¿Funciona si pasas " este " en la función de inicio?

algo como: (sin probar)

var obj = {
    prop:function(){ alert('This just ran.'); },
    init:(function(o){ o.prop(); })(this);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top