Did You Know?
In JavaScript only functions create scopes. More...

JavaScript closures and scope

Posted: January 30th, 2010 | Author: diegoquinteiro | Filed under: Uncategorized | Tags: , | 3 Comments »


Get to know the scope of your variables. In JavaScript only functions can define scopes and only variables explicit declared by using the var keyword are restricted to local scopes, otherwise they’re global. Furthermore, function parameters are also local variables. Pay attention to this example:

function example (arg) {
	var localVariable = 0;
	if (arg > 0) {
		var sameScope = arg + 1;
	}
	localVariable = sameScope;
	alert(localVariable);
	globalVariable = arg;
}

example(1); // Alerts "2"

alert(localVariable); // Alerts "undefined"

alert(sameScopo); // Alerts "undefined"

alert(globalVariable); // Alerta "1"

Notice that the sameScope variable could be assinged to localVariable althought it was declared inside an if block. Blocks doesn’t define scopes, only functions do.

JavaScript always defines a global object, which in the browsers is the window object. All global variables are in fact properties of this object, so:

example(0);

window.example(1); // functions are also variables

alert(globalVariable); // Alerts "1"

alert(window.globalVariable); // Alerts "1" too

alert(globalVariable === window.globalVariable); // Alerts "true"

Closures

Functions in JavaScript are first-class objects. That means you can pass a function to other functions, assign functions to variables or use them as return value. A declaration function functionName (arg1, arg2, …) { … body … } have the same effect as var functionName = function (arg1, arg2, …) { … body … };.

The inner functions always have access to the outer function’s variables. For example:

var outerFunction = function (value) {
    var outerFunctionVariable = value;
    var innerFunction = function () {
        alert(outerFunctionVariable);
    }
    innerFunction();
}

outerFunction(1); // Alerts "1";

Something curious happens when we keep a reference to the inner function after the outer function execution:

var outerFunction = function (value) {
    var outerFunctionVariable = value;
    var innerFunction = function () {
        alert(outerFunctionVariable);
    }
    return innerFunction;
}

var inner1 = outerFunction(1);
var inner2 = outerFunction(2);

inner1(); // Alerts "1"!
inner2(); // Alerts "2"!

That way we created a closure.

Local variables created by the outer function weren’t destroyed even after its execution. By keeping a reference to innerFunction, we also prevented the outerFunction variables to die.

This is a powerful feature of the language, as we will see in next posts.


3 Comments on “JavaScript closures and scope”

  1. 1 Thársis said at 17:55 on April 27th, 2010:

    “Orientação à objeto” não tem crase.

  2. 2 diegoquinteiro said at 21:14 on April 27th, 2010:

    Verdade, obrigado =D

  3. 3 Emily said at 18:50 on June 2nd, 2010:

    Verdade, obrigado =D


Leave a Reply