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 = {},
$chatMessage = $('<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 becausemessageFactorywill not contain the anonymous function, but rather whatever is returned from it. To better understand that, I’ll give an example…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….
Note again that we have an anonymous function being immediately executed. So the variable
sayHiwill not contain the outside anonymous function, but rather it’s return value. SosayHiwill actually containfunction(name){ return salutation + ", " + name + ".";}. You’ll note that we’re not passing insalutation, but we can still access it as it’s part of theclosurethat 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 sayingnew Object(). These objects can have properties and methods the same as a C# object, which is where the.textis coming from that you referred to.On line 2, the code is creating an Object literal:
var that = {}. The next var creation isvar chat = function(message){....where a function is created which takes amessageparameter and does some stuff with it. Towards the end of the code, thatchatfunction is then assigned to thechatproperty ofthatand thenthatis returned:that.chat = chatandreturn that.The point of all this is that
messageFactorydoes not contain the function it appears to be assigned to, but rather thereturnof that function. In this case, that return is actually thethatObject, which has two properties ofchatandsystem. Those properties actually point back to thechatandsystemvariables inside the same closure thatthatwas 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 anObjectas a parameter to thechatfunction inside the closure. It then references the object’snickandtextproperties 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.