First, a pseudo code example:
;(function(foo){
foo.init = function(baz) { ... }
foo.other = function() { ... }
return foo;
}(window.FOO = window.FOO || {}));
Called like so:
FOO.init();
My question:
- What is the technical name/description of:
window.FOO = window.FOO || {}?
I understand what the code does… See below for my reason(s) for asking.
Reason for asking:
I’m calling the passed in global like so:
;(function(foo){
... foo vs. FOO, anyone else potentially confused? ...
}(window.FOO = window.FOO || {}));
… but I just don’t like calling that lowercase “foo“, considering that the global is called capitalized FOO… It just seems confusing.
If I knew the technical name of this technique, I could say:
;(function(technicalname){
... do something with technicalname, not to be confused with FOO ...
}(window.FOO = window.FOO || {}));
I’ve seen a recent (awesome) example where they called it “exports“:
;(function(exports){
...
}(window.Lib = window.Lib || {}));
I guess I’m just trying to standardize my coding conventions… I’d like to learn what the pros do and how they think (that’s why I’m asking here)!
Pattern
There is no formal name for the pattern you describe, because it’s three separate patterns combined. Each pattern goes by multiple names, but for this post I will use the following terminology:
Closure
The base of the entire pattern is the
closure. It is simply a function that is used to scope variables and functions such that they don’t pollute the global namespace:No closure
Closure, in this case, an Immediately Invoked Functional Expression (IIFE)
The advantage of keeping variables within a closure is that you won’t have to worry about someone overwriting the variables that you’re using. This is especially important for temporary variables such as
iorjthat are used often.Alias
The second important part of this pattern is aliasing. Aliasing allows a variable to be defined and used within a closure without needing to worry about what global namespace it resides in.
Without Aliasing
With Aliasing
This is especially important as it means that the global namespace can be changed across a large JavaScript file by changing the name in a single location. This is A Good Thing™. Additionally, minifiers can shorten the internal alias to a single letter variable name such as
a, making for significant byte savings on minification.Namespace Extension
The namespace extension pattern relies on the coalescing behavior of the or operator (
||). In many languages,&&and||return eithertrueorfalse, but in JavaScript,&&returns the firstfalseyvalue (false,0,'',null,undefined), and||returns the firsttruthyvalue (anything that’s notfalsey). For both operators, if the respective type is not found, the last argument is returned. This makes the||operator a convenient way of defining a new namespace only if it doesn’t already exist.Without namespace extension
With namespace extension
This is useful because it allows a namespace to be extended with additional properties and methods without having to worry about which order the properties and methods were defined in.
In this first example,
FileAwould need to be executed beforeFileB:FileA.js
FileB.js
In this second example,
File1andFile2could be executed in any order:File1.js
File2.js
All together now
Using each pattern together creates a very powerful modular script: