开发者

How does the following function call work in Javascript

I've been playing with the code associated with this really cool article.

In the articles code a variable is assigned a function as follows:

var messageFactory = (function() {
    var that = {},
        $chatMess开发者_如何学JAVAage = $('<p></p>').
          addClass('chat message'),
        $nick = $('<span></span>').
          addClass('nick'),
        $systemMessage = $('<p></p>').
          addClass('system message');

    var chat = function(message) {
      var $filledNick = $nick.clone().
            text(message.nick + ':');
      return $chatMessage.clone().
        append($filledNick).
        append(message.text);
    };

    var system = function(message) {
      return $systemMessage.clone().text(message.text);
    };

    that.chat = chat;
    that.system = system;

    return that;
  })();

Later sub functions are called like the following,

messageFactory.system({ text: 'You changed your nick to ' + nick + '.'})

and

messageFactory.chat({ nick: 'me', text: message })

What's going on in those calls? Specifically it appears that the var messageFactory is working similar to a class definition in language like C#, and I'm missing the scope related mechanisms to how the values are being passed via the object { text: '...' ...}.

Thanks much!


The first and arguably most important thing to note is the last line. Specifically, the () before the ;. What this is doing is immediately executing the anonymous function on line 1. This is important to note because messageFactory will not contain the anonymous function, but rather whatever is returned from it. To better understand that, I'll give an example...

var x = (function(){ return "Hello!"; })();
// x will contain "Hello!", not the function.

The second thing to keep in mind is that objects in Javascript will maintain a reference to the closure that they were created in. So if you immediately execute a function like we're doing above, that will a form a closure and objects created in that closure will maintain a reference to it even after the function is done executing. Another example....

var sayHi = (function(){ 
    var salutation = "Hello";
    return function(name) {
       return salutation + ", " + name + ".";
    }
})();

Note again that we have an anonymous function being immediately executed. So the variable sayHi will not contain the outside anonymous function, but rather it's return value. So sayHi will actually contain function(name){ return salutation + ", " + name + ".";}. You'll note that we're not passing in salutation, but we can still access it as it's part of the closure that this function was created in.

The final thing to understand the provided code is that in Javascript, {} is an Object literal. It's essentially equivalent to saying new Object(). These objects can have properties and methods the same as a C# object, which is where the .text is coming from that you referred to.

On line 2, the code is creating an Object literal: var that = {}. The next var creation is var chat = function(message){.... where a function is created which takes a message parameter and does some stuff with it. Towards the end of the code, that chat function is then assigned to the chat property of that and then that is returned: that.chat = chat and return that.

The point of all this is that messageFactory does not contain the function it appears to be assigned to, but rather the return of that function. In this case, that return is actually the that Object, which has two properties of chat and system. Those properties actually point back to the chat and system variables inside the same closure that that was created in, which makes this all work.

The final piece is simple enough.... when you call messageFactory.chat({ text: 'something', nick:Joe}) you're actually passing an Object as a parameter to the chat function inside the closure. It then references the object's nick and text properties to return its result.

Hope that helps. I'm not sure I explained it very well, but that's kind of how it works in my head.


It's anonymous class declaration and instantiation

http://jasonwyatt.tumblr.com/post/866536821/anonymous-classes-with-javascript-and-self-calling

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜