模块模式如何知道如何在这里调用构造函数?

时间:2012-04-11 21:08:57

标签: javascript

外部var消息和内部var消息之间的连接是什么?

致电

new Message ( element ).display( server_response_text.slice( 6 ) );

对象

var Message = ( function () 
{
    var messages = 
    {
        name:         'Please enter a valid name',
        email:        'Please enter a valid email',
        email_s:      'Please enter a valid email.',
        pass:         'Please enter passoword, 6-40 characters',
        url:          'Please enter a valid url',
        title:        'Please enter a valid title',
        tweet:        'Please enter a valid tweet',
        empty:        'Please complete all fields',
        same:         'Please make emails equal',
        taken:        'Sorry, that email is taken',
        validate:     'Please contact <a class="d" href="mailto:here@host.com">support</a> to reset your password',
    };
    var Message = function (element) 
    {
        this.element = element;
    };
    Message.prototype.display = function( type ) 
    {
        this.element.innerHTML = messages[ type ];
        new Effects().fade( this.element, 'down', 4000 );
    };
    return Message;
} () );

我的整个图书馆正在使用像这样的模块模式

    var NS = ( function ( window, undefined ) 
    {
    /*
    all code here including Message
    */
    } )( window );

3 个答案:

答案 0 :(得分:3)

这些变量引用是相同的,尽管名称相同。

在匿名函数中,Message是本地声明的构造函数 在函数末尾返回对此构造函数的引用。

身份测试:

window.Message = ( function () {
    ...
    // Defer call
    setTimeout(function() {
        alert('Identity? ' + Message === window.Message);
    }, 100);
    return Message;
} () );

图片:

  • 绿色 Message对象(构造函数)在红色块(函数)中定义。
  • 在此函数结束时,将返回创建的绿色Message对象。
  • 在创建函数之后,使用 () 调用它。返回值(绿框)将传递给橙色 Message变量。
  • 现在,橙色 Message变量指向绿色 Message对象/构造函数。澄清:绿色和橙色Message变量引用同一个对象
  • 使用new operator
  • 创建此构造函数的实例

答案 1 :(得分:1)

外部Message被设置为立即函数调用的结果(“(function()...”)。立即函数的返回值是内部Message,它也被设置为一个函数(只是在“var messages”关闭范围之后,“var Message = function(element)”函数。)。

当您在此代码之外调用新消息时,它将调用“var Message = function(element)”函数来构造对象。

使用此表单的原因是“消息”保存在一个闭包中 - 本质上,它是私有数据。这是评论版:

var Message = ( function ()     // Immediate function call
{
    // This is going to be private data - it's in a closure via the immediate function call
    var messages = 
    {
        name:         'Please enter a valid name',
        email:        'Please enter a valid email',
        email_s:      'Please enter a valid email.',
        pass:         'Please enter passoword, 6-40 characters',
        url:          'Please enter a valid url',
        title:        'Please enter a valid title',
        tweet:        'Please enter a valid tweet',
        empty:        'Please complete all fields',
        same:         'Please make emails equal',
        taken:        'Sorry, that email is taken',
        validate:     'Please contact <a class="d" href="mailto:here@host.com">support</a> to reset your password',
    };

    // This will be returned as the actual value of outer Message
    var Message = function (element) 
    {
        this.element = element;
    };

    // This adds to the prototype so it will be found in all instances of Message objects
    Message.prototype.display = function( type ) 
    {
        this.element.innerHTML = messages[ type ];
        new Effects().fade( this.element, 'down', 4000 );
    };

    // This is the return value of the immediate function call and becomes outer Message
    return Message;
} () );

答案 2 :(得分:1)

根本没有与变量名称 1 的关系。

这只是里面使用的名字。它也可能是fuubar

var fuubar = function (element) 
{
    this.element = element;
};
fuubar.prototype.display = function( type ) 
{
    this.element.innerHTML = messages[ type ];
    new Effects().fade( this.element, 'down', 4000 );
};
return fuubar; // the Object is returned, the Variable (Name) is not

外部名称是Message是有意义的,因为这是其他人“知道”的方式。 1 内部名称可能是为了保持一致性,但不会影响语义。

构造函数只是使用 new 运算符调用的函数对象[设计]。变量可以命名对象。在这种情况下,请注意返回的是 function-object 。因此, function-object 在名称Message(例如“被分配给消息”)之外是已知的。但是,变量不是对象

因此new X()计算表达式X,它必须求值为函数对象,然后将其用作构造函数。 (构造函数只是一个期望与new一起使用的普通函数:它可以执行初始化并建立[[prototype]])。名称X 不重要,除非它必须评估为函数对象。请考虑使用此等效表单来显示:new (X)()。表达式(X)首先评估

所以,让我们分解代码:

var Message = (function () {
   // This function is invoked immediately, due to the
   // parenthesis immediately after the FunctionExpression.
   // As noted above the name Message used inside is not important.
   // What *IS* important is that a Constructor, which is just
   // a function-object (which is just an object) is returned.
   // This returned object will be assigned to (the outer)
   // Message variable. That is, it is "named by Message"
   // after the assignment occurs.
})()

// At this point Message will evaluate to a function-object
// (a Constructor in particular).
Message instanceof Function // -> true

// And we can use it to create new messages:
var messageA = new Message("a")
var messageB = new Message("b")

快乐的编码。