What are free variables?

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.


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.


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.