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.

Karl Bielefeldt
  • 146,727
  • 38
  • 279
  • 479
  • 2
    You are correct that the example you're quoting is contrived and excessively complex for what it is doing. – Erik Eidt May 13 '16 at 16:51
  • 1
    Possible duplicate of [What's so useful about closures (in JS)?](http://programmers.stackexchange.com/questions/203507/whats-so-useful-about-closures-in-js) – Robert Harvey May 13 '16 at 16:55

4 Answers4

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"));
Philipp
  • 23,166
  • 6
  • 61
  • 67
  • +1 much better is function is parametrized – Laiv May 13 '16 at 14:53
  • Nice example, but why not just call `CalculateCodeFor(username)` directly? – Robert Harvey May 13 '16 at 16:50
  • @RobertHarvey Because I am trying to explain how closures work. – Philipp May 13 '16 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). – Robert Harvey May 13 '16 at 16:52
  • @RobertHarvey I added a second example which you might like better. – Philipp May 13 '16 at 17:03
  • That is a better example. – Robert Harvey May 13 '16 at 17:19
  • All good stuff; however, the OP was not asking what are closures, when are they useful, or for a good example of a closure, but rather inquiring about the point of the cited source code example, and the hunch it could be simplified, and if that were the case, then was there something else of value in the example that was not obvious? As such, I don't think this answers the question being asked. – Erik Eidt May 13 '16 at 18:09
  • @ErikEidt: I think there's enough material here (including the comment below the question) to allow the OP to draw the conclusion that the example he gave is too contrived to be a good example. – Robert Harvey May 13 '16 at 18:13
  • Well, as I said, all good stuff; however, I think @Karl's answer goes more to the actual question asked, which I take as being more about the point the tutorial is trying to make (although badly, perhaps). – Erik Eidt May 13 '16 at 18:19
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.

Karl Bielefeldt
  • 146,727
  • 38
  • 279
  • 479
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.

Cort Ammon
  • 10,840
  • 3
  • 23
  • 32
  • 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. – ScrollingMarquees May 16 '16 at 15:20
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.

Laiv
  • 14,283
  • 1
  • 31
  • 69
  • 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 May 13 '16 at 16:49
  • @Erik Eidt Excatcly. I have edited the answer highlighting such point. – Laiv May 13 '16 at 18:11