Question

Javascript closure definition says :

A "closure" is an expression (typically a function) that can have free variables together with an environment that binds those variables (that "closes" the expression).

Can some one explain to me the concept of free variables ? Is this concept Javascript specific or applies to other languages also ?

Was it helpful?

Solution

Free variables are simply the variables that are neither locally declared nor passed as parameter.

Source :

In computer programming, the term free variable refers to variables used in a function that are not local variables nor parameters of that function.1 The term non-local variable is often a synonym in this context.

In javascript closures, those are simply the variables that the function takes (read and write) in the enclosing scope where is declared the closure or in a parent scope.

Look at this real world example :

Gol.prototype._ensureInit = function() {
    ...
    var _this = this;
    var setDim = function() {
        _this.w = _this.canvas.clientWidth;
        _this.h = _this.canvas.clientHeight;
        _this.canvas.width = _this.w;
        _this.canvas.height = _this.h;
        _this.dimChanged = true;
        _this.draw();
    };
    setDim();
    window.addEventListener('resize', setDim);
    ...
};

In this example a closure points from the setDim function towards the variable _this declared in the enclosing scope (the _ensureInit function). This variable isn't declared in setDim nor passed. It's a "free variable".

Note that _this doesn't become a variable of the function setDim : another function declared in the same scope would share the same variable.

OTHER TIPS

A "free-translation" could be: "out of scope" - variables.

Since ECMAscript uses lexical scoping, a free variable is a variable which was defined in a parent-scope and gets looked-up by a scope-chain search.

(function _outerScope() {
    var foo = 42;

    (function _innerScope() {
        var bar = 100;

        console.log( foo + bar ); // 142
    }());
}());

In the above example, foo is a free variable within the context of _innerScope. it becomes very obvious if we have a quick glance into the underlying concepts of ECMAscript.

A Context is linked to an Activation Object (in ES3), respectively a Lexical Enviroment Record (in ES5), which contains things like: function declarations, variables declared with var and formal paramters, as well as a reference to all parent Activation Objects / Lexical Environments. If a variable needs to be accessed, the ECMAscript engine will first look into the AOs / LEs from the current Context itself; if it can't be found there, it looks into the parent AO's / LE's.

Since any Context stores this data in an array-like structure (don't forget we're talking about implementation level here, not Javascript itself), we are talking about Lexical Scope, because we search through all parent Contexts in order.

As an example:

var myModule = (function (){
   var moduleVar; // closure variable

   return function(){
     // actual function
   }
})();

the variable defined there is a closure variable. it can be used all over the closure itself but is not part of a global namespace.

I don't remember how many times I've read JS books and revise some topic in which the closure topic is there.

The answer is just an addition to the accepted answer.

The following example is excerpted from Modern JavaScript for the Impatient, Cay Horstmann

// text is a free variable of the arrow function.
const sayLater = (text, when) => {
  //         vv
  let task = () => console.log(text) // (heed no 'text' variable here) => console.log(text)
  setTimeout(task, when)
}

Now you can grasp the meaning of

The term free variable refers to variables used in a function that are not local variables nor parameters of that function.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top