2

I'm reading the JavaScript guide on MDN and trying to understand the usefulness of closures. This sentence helped me the most, "In other words, the functions defined in the closure 'remember' the environment in which they were created." And I understand that part, but I don't get why this function...

var getCode = (function(){
      var secureCode = "0]Eal(eh&2";    // A code we do not want outsiders to be able to modify...

  return function () {
    return secureCode;
  };
})();

getCode();    // Returns the secureCode

is any better than this function....

var getCode = (function(){
      var secureCode = "0]Eal(eh&2";    // A code we do not want outsiders to be able to modify...
      return secureCode;
})();

getCode();    // Returns the secureCode

secureCode should still be unmodifiable by outsiders due to how JavaScript defines scope within functions.

2

4 Answers 4

1

In your particular contrived example, there is no difference at all. If you only ever use a variable by value, and assign it a compile-time value, it matters not whether you use a closure or not. In fact, the closure may be slower, depending on your browser's JavaScript implementation. This contrived example is simply too simple -- there's no reason to need the extra power of closures.

The example shown was of things that closures can do. In an effort to not distract from the intent of the article, they oversimplified it to something which doesn't actually show the power of a closure at all.

My recommendation would be to look at the other examples on the page. Many others, especially the module pattern example, show the actual power of closures. The module example cannot be done with local variables, while the example you copied into your question could.

1
  • Thank you. The example in question lead to my confusion about the usefulness of closures. You are correct that the example further down the page helped considerably in understanding true power of closures, but in the back of my mind I keep wondering if, as a newcomer to the language, there was something I was missing relating the earlier example. Commented May 16, 2016 at 15:20
4

It's not about an outsider being able to change it. Here is a better example which illustrates the usefulnes of closures:

var getCodeForUser = (function(username){
  var secureCode = CalculateCodeFor(username);

  return function () {
    return secureCode;
  };
})("ScrollingMarquees");

getCodeForUser();    // Returns the secureCode

In this case the closure calculates a value and then generates a function which internally uses that generated value. The inner function remembers that value even when it leaves that scope with return.

You can use the outer function to generate functions for multiple users which will then all "remember" a different secureCode.

Here is a different example which does something completely different but illustrates the usefulness of closures. Here we have a function which makes HTML button elements with a click handler function. Note that the onclick-handler function it generates uses a variable from the local scope which it retains after leaving the scope:

function makeButton(color) {
     var button = document.createElement("button");
     button.style.backgroundColor = color;
     button.innerHTML = color;
     button.onclick = function() {
          alert("I am a " + color + "-colored button");
     }
     return button;
}


var container = document.getElementById("container");

container.appendChild(makeButton("blue"));
container.appendChild(makeButton("red"));
container.appendChild(makeButton("yellow"));
container.appendChild(makeButton("green"));
9
  • +1 much better is function is parametrized
    – Laiv
    Commented May 13, 2016 at 14:53
  • Nice example, but why not just call CalculateCodeFor(username) directly? Commented May 13, 2016 at 16:50
  • @RobertHarvey Because I am trying to explain how closures work.
    – Philipp
    Commented May 13, 2016 at 16:51
  • Sure, but there needs to be a motivation for using the technique. That's what the OP is asking for, not the finer points of closure mechanics (which the OP appears to already understand). Commented May 13, 2016 at 16:52
  • @RobertHarvey I added a second example which you might like better.
    – Philipp
    Commented May 13, 2016 at 17:03
1

People often get excited talking about what closures can do, and they forget to talk about what you should do with closures. Your particular example builds on the previous example, which showed closures acting like poor man's objects. This is far from the best example of idiomatic closure use, but it is familiar to object oriented programmers, which I suppose is why people bring it up so frequently in these types of articles.

Your example continues where the previous example left off, showing that you don't even need to name your closure! It's an interesting bit of trivia. It helps you understand how closures work. It might come in handy in a different context, but as it stands, the example is not very practical, and the author most likely didn't intend it to be.

My answer to a previous related question shows a real example of where closures are actually better than alternatives.

0

Your first approach is closer to clousure concept than first one.

However, that code can be even more clear

var getCode = function(){ 
      var secureCode = "0]Eal(eh&2"; // A code we do not want outsiders to be able to modify... 
       return secureCode; 
 }; 

getCode(); // Returns the secureCode

As you pointed, secureCode is not editable.

Now getCode is an object that can be passed into functions

function method (fnArg){ 
      console.log(fnArg());
}

method(getCode());  //will print a log in browser consolé

You also can attach it to an object

var object ={
     method: getCode
};

//invoke getcode
object.method();

Or attach it to another object that already exist

var objectA = {};
objectA.method = getCode;

objectA.method();

None of these examples have access to secureCode

As you see, this kind of object-functions are really useful.

The principal usage is to use them as callbacks in asynch processes

object.send().onResponse(getCode());

Or

object. send().onError(function (){
      console.error("KO!");
});

Edit: Has Erik pointed these examples are not clousure. Clousures have the drawback that make code hard to read and many times the scope of vars may not be clear.

2
  • 2
    While you point out another way of hiding access, I wanted to point out for other readers that your function is not a closure, unless we consider ordinary functions as degenerative closures. I say this because the function you've written does not close over any variables of outside context. It does, OTOH, a nice job of hiding the variable without excess linguistic machinery.
    – Erik Eidt
    Commented May 13, 2016 at 16:49
  • @Erik Eidt Excatcly. I have edited the answer highlighting such point.
    – Laiv
    Commented May 13, 2016 at 18:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.