Monday, October 12, 2009

Callback Functions - Scoping

According to Wikipedia, a callback function is executable code that is passed as an argument to other code. It allows a lower-level software layer to call a subroutine (or function) defined in a higher-level layer.

Callback functions are used very frequently in event driven software systems. Whenever an event happens, a function is called.

The idea is simple, but many people tend to become confused when using these things. The problem that they encounter is that people tend to run into problems with the scope of variables that they are using.

Part of the problem is remembering that the callback function may form a closure. When the callback function is executed, the scope consists of the callback function's code and references to any variables of the function containing the callback function reference. The converse is not true; the function containing the callback function reference cannot use the arguments and variables of the callback function.

Another thing that can confuse people using callback functions is the use of global variables. Since callbacks are usually called in response to events, it may not be clear what the current state of the system is and using any predefined global variable may result in inconsistent results.

In addition to global variables, variables using the same name in the code containing the reference to the callback function and with in the callback can sometimes confusing to people. In this case, the variable within the callback takes precedence.

# example function with closure

function makePowerTo(x) {
return function(y) {
var result = y;
for (var i = 1; i < x;i++)
result *= y;
return result;
};
}
var square = makePowerTo(2);
var cube = makePowerTo(3);
print(square(2)); // 4
print(cube(2)); // 8

square
and cube are both closures. They share the same function body definition, but store different environments. In square's environment, x is 2. As far as cube is concerned, x is 3.