0

I'm trying to understand (probably simple concepts) about JS, and I've put together the below piece of code to explain what I don't get. What I do not understand is where the name variable is stored. Is that variable now global?

(function($) {

  var name = '';

  $.helloWorld = function(yourName) {
    name = yourName;
    console.log("Hello " + yourName);
  }

}(jQuery));
sbrattla
  • 5,274
  • 3
  • 39
  • 63
  • The variable is scoped to that closure, that's the point of IIFEs, to encapsulate code and not leak variables to the outer scope. – elclanrs Jun 11 '13 at 04:45

2 Answers2

4

The name variable is local to the outer function, because it's declared with the var keyword. The inner function is a closure that contains a reference to that variable. Here's a better example that shows this off:

(function($) {

  var name = '';

  $.setName = function(newName) {
    name = newName;
  }

  $.showName = function() {
    console.log("Name is: " + name);

}(jQuery));

After defining this, you can do:

$.setName("Larry");
$.showName();
$.setName("Fred");
$.showName();

See How do JavaScript closures work?

Community
  • 1
  • 1
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thanks, but how do I access the name variable from the helloWorld function? Is there some way à la Java's this keyword? – sbrattla Jun 11 '13 at 04:46
  • You would access it by referring to it by name (just like any other variable). You could have your helloWorld function print its value like this: `alert(name);` – jahroy Jun 11 '13 at 04:48
  • Alright, so I should also avoid using inner function argument names which conflicts with outer function variable names since I can't really distinguish them from each other like you can with Java? – sbrattla Jun 11 '13 at 04:49
  • Yes. These are just nested function scopes, not objects. – Barmar Jun 11 '13 at 04:51
  • Alright, thanks! Marking this one as the right answer as it was both the first answer and apparently a correct answer :-) – sbrattla Jun 11 '13 at 04:53
2

This should help you understand:

(function(){

    var name;
    var scope1;

    // Here you can use scope1 and name

    (function(){

        var name;  //  <------------------------
        var scope2;                         // |
                                            // |
        // Here you can use scope1,scope2, and name

        (function(){

            var name;   //  <------------------------------
            var scope3;                                 // |
                                                        // |
            // Here you can use scope1,scope2,scope3, and name

        })();

     })();

})();

// Any\variable declared outside of any function scope is in the global scope.
// A variable declared here can be accessed by window.name from any scope
var name = 5;

So in this snippet, 3 scopes are created by the three functions and in the innermost you can access the variables that have unique names (scope1,scope2, and scope3) as well as the local variable name, which is a separate name from the one it the middle scope. Reusing variable names like that to prevent access to the variable in an outer scope is called shadowing.

Note that a variable that is not declared with the var keyword is auotmatically assumed to be in the global scope. It is a bad practice to declare many variables in the global scope as they can easily conflict with other scripts.

Paul
  • 139,544
  • 27
  • 275
  • 264