Created
May 31, 2012 15:40
-
-
Save ignacioiglesias/2844244 to your computer and use it in GitHub Desktop.
My (very) liberal interpretation of JavaScript Module Pattern: In-Depth by Ben Cherry
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is my (very) liberal interpretation of | |
// JavaScript Module Pattern: In-Depth by Ben Cherry | |
// http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth | |
"use strict"; | |
var api = (function(a) { | |
// I will use `a` as the API, so let's say I want to add some stuff, | |
// for instance, a logging module. | |
function privateDebugMethod(message) { | |
console.log(message); | |
} | |
// Same strategy here, I check for any previous existence and, | |
// in case there isn't one, I assign a literal, empty object. | |
a.logging = a.logging || {}; | |
// Because objects created in here retain access to the context | |
// of this closure, I can have private and public scoping. | |
// This public method takes a message string and an optional | |
// generator function that will be called each time the method | |
// is triggered. | |
a.logging.log = function(message, prefixGenerator) { | |
var text = (typeof prefixGenerator === 'function') ? prefixGenerator() : ''; | |
text += message; | |
privateDebugMethod(text); | |
}; | |
return a; | |
}(api || {})); // if there's an API, pass it. If not, use an empty obj. | |
var generator = function() { return Date() + ': '; }; | |
api.logging.log('Hello', generator); // Thu May 31 2012 12:24:54 GMT-0300 (ART): Hello | |
// Now, let's say I want to ping the API: | |
try { | |
console.log(api.ping()); | |
} catch(ex) { | |
console.error(ex); // [TypeError: Object #<Object> has no method 'ping'] | |
console.log('The contents of the API are:', api); //The contents of the API are: { logging: { log: [Function] } } | |
} | |
// Let's pretend we include another module in another file, using the same pattern: | |
var api = (function(a) { | |
// Add a public method to the api | |
a.ping = function() { | |
return 'pong'; | |
}; | |
return a; | |
}(api||{})); | |
console.log('Now the contents are:', api); //Now the contents are: { logging: { log: [Function] }, ping: [Function] } | |
console.log(api.ping()); // pong |
Oh, I didn't know that JS did that. Thanks, man!
(and thanks for your awesome blog <3)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This looks reasonable.
One note, though: As far as I know (and I might be wrong, but my tests in Node/v8 backed up my understanding. Info on the web is sparse on this topic, maybe I'll write a quick blog post to create a reference), you don't need to declare
var ex
on line 37. Thecatch (ex)
will declare a new variable that will be limited to the scope of thecatch
expression (and shadow any variable outside of it). This isn't really intuitive, of course, since JavaScript normally does not have block-level scope, but this appears to be an exception (no pun intended). Further confusing the matter, any variables declared within the body of thecatch
will be available outside (and hoisted appropriately).