JavaScript - 对象初始化器?

22

我意识到可以像这样自动运行对象中的属性:

var obj = {

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

}

我正在尝试将此方法用作对象的初始化程序。我遇到的问题是将对'obj'的引用传递给init属性。我怀疑这会产生错误,因为obj在浏览器中尚未完全构建。我正在尝试以下操作,但没有成功。如果有方法可以完成这个任务,我很想知道如何做。

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

23

如果你想创建多个相似对象的实例,应该使用纯旧构造函数(记得将共享属性放在原型中!)。

如果你想创建一个单一对象,请考虑使用匿名构造函数。你的示例代码可以这样写:

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

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

相较于对象字面量,这样做还有一个额外的好处:构造函数可以用作“私有”变量的闭包。

不要过度使用对象字面量:它们可能会让简单的事情变得更简单,但复杂的事情会变得过于复杂。


有趣。你知道在哪里可以找到关于这些匿名构造函数的文档吗? - JW.
1
@JW,我认为匿名构造函数只是一个匿名函数被用作构造函数(即使用new关键字调用)。另请参阅https://dev59.com/EnnZa4cB1Zd3GeqPoEl6和http://enfinery.com/30/javascript-the-case-of-an-anonymous-constructor。 - jacobq

5
这是不可能的:obj直到整个代码块被解释完才存在。

4
一个简单的替代方案:
var obj = {

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

}.init();

2
需要注意的是,这将obj设置为init()返回的任何值 - 在此示例中为undefined - nnnnnn

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

不在构造函数中初始化的原因是每次需要原型(例如制作子类)时都需要调用构造函数 - function 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) } )()
}

如果在var语句之后的下一行需要使用obj.prop,那么这种方法将无法正常工作。 - nnnnnn

1

这是对用户1575313提交的示例进行更新。

原始代码可以工作,但它限制了设置后对象的使用。通过在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();

1

使用类似于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


0

我认为你想尝试这样的代码:

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

对象字面量需要逗号分隔的成员,不要使用分号。


这不会在创建时运行init函数。 - Andrew Bullock
你是正确的 - 没有任何方法可以使用对象字面量来做到那一点。 - Andrew Hare

-1

如果将“this”传递到init函数中,它能工作吗?

类似这样:(未经测试)

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

2
不,传递的是对 window.object 的引用。 - Geuis
1
虽然不是直接相关的,但你可以使用http://jsfiddle.net/快速原型和测试东西。 - Audrius

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接