2009-03-08 4 views
18

Я понял, что вы можете иметь свойство объекта запускается автоматически, как это:Javascript - инициализатор объекта?

var obj = { 

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

} 

Я пытаюсь использовать этот метод в качестве инициализатора для объекта. Проблема, с которой я сталкиваюсь, - передать ссылку на объект obj на свойство init. Я подозреваю, что он генерирует ошибки, потому что obj еще не был полностью создан в браузере. Я пытаюсь сделать следующее, но безуспешно. Если есть способ сделать это, я хотел бы знать, как это сделать.

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

ответ

21

Если вы хотите создать несколько экземпляров аналогичные объекты, вы должны использовать простые старые конструкторские функции (не забудьте поместить общие свойства в прототип!).

Если вы хотите создать отдельный объект, подумайте об использовании анонимного конструктора. Ваш пример будет гласить:

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

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

Это имеет дополнительное преимущество над литералами объектов: функция конструктора может быть использована в качестве закрытия над «частными» переменными.

Не злоупотребляйте литералами объектов: они могут сделать простые вещи простыми, но сложные вещи будут чрезмерно сложными.

+0

Интересно. Вы знаете, где я могу найти документацию по этим анонимным конструкторам? –

+1

@JW, я считаю, анонимный конструктор - это просто анонимная функция, используемая в качестве конструктора (т. Е. Вызываемая с ключевым словом 'new'). См. Также http://stackoverflow.com/questions/20057431/javascript-anonymous-constructor-function-function и http://enfinery.com/30/javascript-the-case-of-an-anonymous-constructor – iX3

-1

Это работает, если вы передадите «это» в функцию init?

что-то вроде: (непроверенные)

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

Nah. Передача (это) является ссылкой на window.object – Geuis

+1

Непосредственно, но вы можете быстро прототипировать и протестировать материал, используя http://jsfiddle.net/ – Audrius

0

Я думаю, что вы хотите попробовать что-то вроде этого: литералы

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

объекта reqire запятой пользователей без запятой.

+0

, которые не будут запускать функцию init при создании, хотя –

+0

Вы правы - есть 't любой способ сделать это с объектными литералами. –

5

Это невозможно: obj не существует, пока весь блок не будет интерпретирован.

3

Почему вы не используете модель застройщик (на самом деле, я понятия не имею, его правильное название):

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

Использование:

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

Причиной не инициализации в конструкторе является то, что вам нужно вызывать конструктор каждый раз, когда вы хотите прототип (например, сделать подкласс) - функция XObj() {...}; XObj.prototype = new Obj() ;. В этом случае вы не хотите инициализировать фактический экземпляр. – bobince

2

Да, obj, кажется, не существует локально до более позднего времени. Это работало для меня с setTimeout. Проверено на IE8, FF5, Chrome 12, Opera v11.5. Не уверен, что за 50 миллисекунд, я думаю, этого достаточно.

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

Это выиграло Не работайте, если следующая строка после оператора 'var' должна использовать' obj.prop'. – nnnnnn

1

Init в 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

4

Простая альтернатива:

var obj = { 

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

}.init(); 
+2

Отмечая, что это устанавливает 'obj' любое значение' init() 'return - которое в этом примере является' undefined'. – nnnnnn

1

это обновление к примеру, представленному user1575313.

Исходный код работает, но он ограничивает использование объекта после установки.Возвращая ссылку на объект в методе init, он позволяет использовать объект вне объекта.

ссылка на 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();