1

I am learning javascript closures.

I have a function

function outer(x){
     var y = 10;
     function inner(z){
         return x + y + z;
     }
     console.log(inner(20));
}
outer(30);

I get the output as 60.

Is this a good example of closure?

user544079
  • 16,109
  • 42
  • 115
  • 171
  • See http://stackoverflow.com/questions/1801957/what-exactly-does-closure-refer-to-in-javascript. –  Aug 27 '14 at 03:33

1 Answers1

2

There is a lot of misunderstanding about closures. The OP is an example of lexical scope, i.e. an "inner" function that has access to the outer function's variables.

Some argue that every function in ECMAScript forms a closure with its outer execution context, however this definition doesn't indicate the wider and more powerful aspects of closures.

The following demonstrates the "every function creates a closure" concept.

var x = 'global x';

function foo() {
  console.log(x);
}

function bar() {
  var x = 'local x';
  foo();
}

bar(); // 'global x'

When foo is created, it's scope is defined and it has access to x in the global execution context. When bar is called, it creates a new execution context and calls foo. Since foo's scope chain is created based on where it's defined in the code, not by where it's called from, it resolves x to be the global variable rather then the one local to bar. So foo has a closure to the global execution context containing x (and all other global variables).

This demonstrates the lexical scope nature of ECMAScript and a "trivial" closure. It's not exploited or allowed to persist so whether it actually existed or not is conjecture.

The more remarkable aspects of closures result from leveraging their ability to access local variables after the execution context that created them has completed, e.g.

var foo = (function() {
  var closureVariable = 'foo';
  return function() {
    console.log(closureVariable);
  }
}());

foo();  // 'foo'

In the above, the immediately invoked function expression (IIFE) creates an execution context with a variable called closureVariable and assigns it a value. It then returns an inner function object that has this variable on its scope chain.

Once the IIFE returns, its execution context remains accessible to the returned function (now referenced by foo). It is this continued access to a completed execution context that allows closures to leverage shared variables that are "private" to certain "privileged" functions, e.g.

var bar = (function() {
  var a;
  return {
    setA: function(value) {
            a = value;
    },
    getA: function() {
            return a;
    }
  }
}());

bar.setA(6);
console.log(bar.getA()); // 6 

The methods setA and getA have a closure to the execution context that created them, and so have shared privileged access to a. It is this persistence of access to otherwise inaccessible variables that is the far more important characteristic of closures.

There is a far more exhaustive explanation on the comp.lang.javascript FAQ notes on Closures.

There is also Douglas Crockford's Private Members in JavaScript.

Edit

The above has been amended to incorporate features from a long discussion of closures on comp.lang.javasscript: Confusion about closures.

RobG
  • 142,382
  • 31
  • 172
  • 209
  • A brief review of what's out there seems to indicate that there is some ambiguity about the definition of closure, specifically, whether the function reference must be persisted or held somewhere outside the enclosing scope for it to be considered a closure. I understand that the narrow sense of closures is not very interesting, and that most people use the term to refer to the case where a function carries its outer scope around with it, but are you aware of any definitive reference for the definition? –  Aug 27 '14 at 03:27
  • The clj FAQ reference above is pretty authoritative (the primary author is Richard Cornford, search for his [*posts on clj*](https://groups.google.com/forum/#!topicsearchin/comp.lang.javascript/authorname$3A%22richard$20cornford%22)), also [*Wikipedia*](http://en.wikipedia.org/wiki/Closure_(computer_programming)): `A closure…allows a function to access those non-local variables even when invoked outside its immediate lexical scope`. I'm sure there are other references, but those two should suffice. – RobG Aug 27 '14 at 04:22
  • @torazaburo—you set me on a search for examples and in the process discovered a long forgotten thread on the subject. Thanks. I've updated the answer to incorporate themes from the thread, feel free to comment further. :-) – RobG Aug 27 '14 at 06:09
  • Thanks, great info. I guess the bottom line is "opinions vary". Personally, I like the "non-trivial closure" terminology. –  Aug 27 '14 at 08:08