0

I have read on stackoverflow that the benefit of IIFE pattern in implementing modules instead of just "named function declaration" is that, in large projects, it can prevent name collisions. However, it seems to me that IIFE is no more better or worse than a named function declaration for preventing name collision.

Consider 2 methods of writing a library which exposes a name called "GenericModuleName":

IIFE approach

var GenericModuleName = (function () {
    return ObjectWhichHasPublicMethod;
})();

Named function declaration approach

function GenericModuleName() {
    return {
        PublicMethod : function () { privateMethod(); }
    }
};

In both cases, if the user of the library coincidentally also has a function named GenericModuleName, there will still be a name clash, isn't it? So how is IIFE better than "named function declaration" in preventing name collision?

Community
  • 1
  • 1
moog
  • 383
  • 5
  • 13
  • The question you link to doesn't give a name to the IIFE, it uses an anonymous function. There's no name conflict because there's no name. – Barmar Aug 01 '16 at 08:28
  • There's nothing you can do to prevent conflicts if two libraries have the same name for the module itself. The idea is to prevent conflicts between functions in different modules. – Barmar Aug 01 '16 at 08:31
  • @Barmar In real life, wouldn't the IIFE be named in order for it to be callable? – moog Aug 01 '16 at 08:33
  • No. Putting `()` after the definition calls it immediately. That's why it's called "Immediately-Invoked Function Expression". – Barmar Aug 01 '16 at 08:35
  • I don't understand "Prevent conflicts between functions in different modules". I thought conflicts between functions in different modules is impossible, because ModuleA's foo will never conflict with ModuleB's foo as foo has to be qualified by the ModuleA or ModuleB instance, like a.foo or b.foo? – moog Aug 01 '16 at 08:36
  • That's my point. The only conflict you'll get is if both modules are called `ModuleA`, since that's the name of the IIFE. – Barmar Aug 01 '16 at 08:37
  • Barmar @Quentin Thanks for both your replies. Both your answers (If I understood correctly) reinforce my thinking that IIFE is no more inferior/superior than a named function declaration in terms of encapsulation or avoiding name collision in a large project. (Please correct me if I understood wrongly.) Which leaves me wondering why IIFE is such a popular explanation for how to build up Javascript modules ... there's no extra benefit for the verbosity. – moog Aug 01 '16 at 08:43
  • Where did you get the idea that one is supposed to be superior to the other? You give it a name if you need to refer to it later (like `jQuery`), you don't give it a name if you just need to call it once to initialize the module. – Barmar Aug 01 '16 at 08:48

1 Answers1

1

Your two examples aren't really comparable.

One creates a global containing an object with public methods. The other greats a global that is a function which will return an object with public methods.

An actual equivalent would be:

var GenericModuleName = ObjectWhichHasPublicMethod;

… but the benefits don't come from avoiding a name clash with GenericModuleName. They come from avoid a name clash with every other variable.

var GenericModuleName = function() {

    var i = 0;

    function privateMethod() {
        return i++;
    }

    return {
        PublicMethod : function PublicMethod() { privateMethod(); }
    }
}();

Neither i nor privateMethod are globals, so they can't clash with other globals.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335