2

I see a lot of code like:

var myApp ={};
(function() {
    console.log("Hello");
    this.var1 = "mark";     //"this" is global, because it runs immediately on load.  Caller is global
    myApp.sayGoodbye = function() {
        console.log("Goodbye");
    };
})();

Which causes the anonymous function to execute immediately. But what is the advantage of this, compared to just putting the code inline?

var myApp ={};
console.log("Hello");
var1 = "mark";     
myApp.sayGoodbye = function() {
    console.log("Goodbye");
};

Apparently it's to do with scope of the function, but as the function is anonymous and called by window, it's scope (i.e. this) is global, no?

Rob
  • 415,655
  • 72
  • 787
  • 1,044
Mark
  • 1,754
  • 3
  • 26
  • 43
  • in the second snippet , var1 is attached to window scope, in the first it is not. – mpm Jan 14 '13 at 11:59
  • But when I step through example 1 with Chrome, `var1` is global. – Mark Jan 14 '13 at 12:02
  • The reason for this structure isn't in the code we see. Or it's totally useless. Please show us more code. – Denys Séguret Jan 14 '13 at 12:04
  • I think the latter doesn't work in strict mode – John Dvorak Jan 14 '13 at 12:04
  • @dystroy - This is an example, there is no other code. According to Chrome, `var1` is global each time. – Mark Jan 14 '13 at 12:07
  • This code doesn't even make sense per se as var1 isn't used. So it's hard to tell why you would have used this construct. – Denys Séguret Jan 14 '13 at 12:08
  • anonymous functions dont change the value of `this` so in the first example youre doing `window.var1 = "mark"` – VeXii Jan 14 '13 at 12:12
  • @VeXii - I realise that (I even put in in the comment in the code!). My question is why people wrap code in anon functions, when it adds complexity. I must have missed something, because there seems to be no advantage to me, but it's the recommended method. Hence the question - why is example 1 better than 2? – Mark Jan 14 '13 at 12:14
  • Simply : It's not better. This example makes no sense without context. – Denys Séguret Jan 14 '13 at 12:24
  • well if you where to use variables insted of adding to the global object, you can scoope. but the exampels like this dont make sense – VeXii Jan 14 '13 at 12:39

2 Answers2

5

Usually, you would have this :

        var myApp ={};
        (function() {
            console.log("Hello");
            var var1 = "mark";  
            myApp.sayGoodbye = function() {
                console.log("Goodbye");
            };
        })();

The main difference is that var1 doesn't clutter the global namespace. After this call, var1 is still the same than before (generally undefined).

As var1 can only be accessed from the function defineds in the closure, it is said "private".

Apart avoiding possible causes of conflicts, it's just cleaner not to keep global variables when useless.

Here, you don't have a local variable but a global one defined as this.var1. It's probably a bug, or the reason would be found elsewhere in the code.

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • Thanks, I think this is the closest explanation. As long as you `var` declare variables within the anon fn, they don't leak out to the global namespace. I find the definition of `this` in javascript very confusing! – Mark Jan 14 '13 at 13:56
3

One reason: wrapping your code in an anonymous function allows you to create a module which distinguishes a public API from private functions and variables that are only used internally to the module. This avoids polluting the global namespace.

var myApp ={};
(function() {
    console.log("Hello");
    this.var1 = "mark";

    function helper() {/*Some code here*/;}

    myApp.sayGoodbye = function() {
        helper()
        console.log("Goodbye");
    };
})();

I could say:

var myApp ={};
console.log("Hello");
var var1 = "mark";

function helper() {/*Some code here*/;}

myApp.sayGoodbye = function() {
    helper()
    console.log("Goodbye");
};

But then the global scope includes a function called helper which is of no use to anyone using your module, and could lead to possible naming conflicts with other modules.

I could alternatively just include helper as a method of myApp.

var myApp ={};
console.log("Hello");
var var1 = "mark";

myApp.helper = function() {/*Some code here*/;}

myApp.sayGoodbye = function() {
    this.helper()
    console.log("Goodbye");
};

However, I may wish to prevent users from directly calling helper, in which case this won't do.

samfrances
  • 3,405
  • 3
  • 25
  • 40