3

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)!

hippietrail
  • 15,848
  • 18
  • 99
  • 158
mhulse
  • 4,062
  • 6
  • 28
  • 35
  • You could call the argument `FOO`. That will hide `window.FOO` unless you explicitly reference it using `window.FOO`. – icktoofay Oct 08 '12 at 03:04
  • 4
    http://stackoverflow.com/questions/6439579/what-does-var-foo-foo-mean-in-javascript –  Oct 08 '12 at 03:12
  • 1
    They're the same object. Feel free to give the the same name or different name. `alert(window.FOO === foo); // true` There is no technical name. It depends on its use. If you're exposing a library, refer to it as your library. If you're exporting a `Foo` constructor, call it the `Foo` constructor. – I Hate Lazy Oct 08 '12 at 03:12
  • Thank you for the comments folks, I really appreciate the help. @icktoofay I have never thought to reference `window.FOO` inside my IIFE; I have always referenced its `Alias` (thanks zzzzBov). So, using `FOO` would work for me. @pst Thank you for the linkage! Sorry that I missed that thread. @user1689607 Thanks for the clarifications, I really appreciate it! Thanks to everyone for the help... I owe you all several Oregon micro brews. :) – mhulse Oct 08 '12 at 22:38

4 Answers4

4
Pattern
(function (foo) {
    ...code...
    foo.bar = baz;
    ...more code...
}(window.FOO = window.FOO || {});

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
  • alias
  • namespace extension

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
//these declare window.foo and window.bar respectively
//as such, they pollute the global namespace
var foo;
function bar() {}
Closure, in this case, an Immediately Invoked Functional Expression (IIFE)
(function () {
    //these declare foo and bar within the function
    //but they are not accessible outside the function
    var foo;
    function bar() {}
}());

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 i or j that 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
(function () {
    ...
    foo = window.SomeFunction(bar, baz);
    ...
}());
With Aliasing
(function (sf) { //local name
    ...
    foo = sf(bar, baz);
    ...
}(window.SomeFunction)); //global namespace

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 either true or false, but in JavaScript, && returns the first falsey value (false, 0, '', null, undefined), and || returns the first truthy value (anything that's not falsey). 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
if (typeof window.Foo === 'undefined') {
    window.foo = {};
}
With namespace extension
window.foo = window.foo || {};

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, FileA would need to be executed before FileB:

FileA.js
window.foo = {};
window.foo.bar = 'baz';
FileB.js
window.foo.fizz = 'buzz';

In this second example, File1 and File2 could be executed in any order:

File1.js
window.foo = window.foo || {};
window.foo.bar = 'baz';
File2.js
window.foo = window.foo || {};
window.foo.fizz = 'buzz';

All together now

Using each pattern together creates a very powerful modular script:

//use foo internally so that you don't have to worry about
//what the global namespace is called
(function (foo) {
    //declare variables internally that you want to keep local to the script
    var i,
        len,
        internal,
        qux;
    //declare functions/properties on the alias when you want to expose them
    foo.bar = function () {...};
//extend the global namespace so that existing extensions are persistent
}(window.FOO = window.FOO || {}));
zzzzBov
  • 174,988
  • 54
  • 320
  • 367
  • Thank you @zzzzBov! Your answer (and all the other answers) really helped me out! The only thing I might add to your reply is Pete's info about it being called "Null Coalescing"? Thanks again! I really appreciate the pro help! – mhulse Oct 08 '12 at 22:05
  • I forgot to say: Thanks for pointing out that I am using **three** patterns! I had no idea. For some reason, I was under the assumption that I was just using a "singleton" IIFE. (I feel like such a noob!) :) – mhulse Oct 08 '12 at 22:33
  • @MickyHulse, in a way JavaScript's `||` operator acts similarly to the null coalescing operator in C#, but it's enough different that I wouldn't call it a null coalescing operator. As far as using multiple patterns goes, a car typically fits a described pattern, but it's made up of many smaller patterns, like wheels axles, and doors, that all come together to make the car. – zzzzBov Oct 09 '12 at 00:30
  • Ahh, I see now. Thank you @zzzBov! I really appreciate you (and everyone else too) taking the time to help out a noob like me. :) – mhulse Oct 09 '12 at 17:23
  • I wouldn't use the term "coalescing" for this at all - it's normally called "short circuit evaluation". If you know the left hand operand of an `||` operator is "truthy" then the right hand operand's value is irrelevant. – Alnitak Jul 31 '13 at 08:09
  • @Alnitak, the short circuit evaluation behavior exists in many languages that use `&&` and `||`, however in most other languages `&&` and `||` will return a boolean value, while ECMAScript returns the values of the operand. That is why I used "coalescing". – zzzzBov Jul 31 '13 at 13:06
2

I've always understood it as "Null Coalescing".

As for affecting your IIFE, you are passing in window.FOO if it is already instantiated, or an empty object if it is not.

You could also read it as:

window.FOO = window.FOO || {};
;(function(foo){

    foo.init = function(baz) { ... }

    foo.other = function() { ... }

    return foo;

}(window.FOO));

Personally, I prefer a different pattern:

var FOO;
if (!FOO) {
    FOO = {};
}
(function () {
    "use strict";
    FOO.prop1 = 'bar';
    FOO.bar = function (z) {
        return z + 1;
    };
}());

I find it to be less confusing and helps me to ensure clean namespacing.

pete
  • 24,141
  • 4
  • 37
  • 51
  • Thank you @pete! This is great info... "Null Coalescing" is a new term to me! I'm researching that now, thank you so much for your pro help and examples! :) – mhulse Oct 08 '12 at 22:10
2

To complement pete's answer, an alternate form:

;(function() {
  var Foo = window.Foo = window.Foo || {};

  Foo.foo  = 'bar';
  Foo.baz  = function() {
    return "Hello World!";
  };
})();

I usually use the local var to give the minifier the opportunity to save a few bytes. This has a bigger effect when you are working on several levels deep in your namespace like on var MyView = window.MyApp.Views.MyView.

Renato Zannon
  • 28,805
  • 6
  • 38
  • 42
  • Thank you Renato! That's very helpful. It's great seeing multiple examples... I am learning a ton from all of you awesome JS gurus! :) – mhulse Oct 08 '12 at 22:08
1

As others have noted, your first question is completely separate and independent of your second question. They have nothing to do with each other except for the fact that you have decided to combine them in a single statement rather than doing it in two statements.

For you first question, Douglas Crockford calls it default assignment. As in, if the variable exists then leave it alone otherwise initialize it to the specified default value. When you see something that looks like:

foo = foo || {};

Your mind's eye should read it as:

foo defaults to `{}`

Technically it's really "assign {} to foo if foo is falsy" but we've made the assumption that anything falsy such as zero, null or undefined is an invalid value for foo when we use this. Also, the word default already implies "if foo is not defined".

But, having said that and knowing your second question it's obvious that default is not really an appropriate word as the name of the parameter passed to your IIFE. What that parameter is doing is simply attach methods and attributes to the object passed in. In which case exports is appropriate as in "these are the publicly exported members of the object". I would think attach is also an appropriate name as in "attach these things to the object". My personal preference is simply to name it obj as in object, which is the type of thing you expect to be passed in.

slebetman
  • 109,858
  • 19
  • 140
  • 171
  • Thank you slebetman! That's very helpful! Sorry that my original question was a little all over the place... I'm still new to some of these advanced techniques and concepts. I really appreciate you (and everyone else who replied) taking the time to answer my questions and teach some new stuff. :) – mhulse Oct 08 '12 at 22:11