I\'ve been reading some JavaScript books and I always hear about closures and side effects. For some reason I can\'t understand what they really are. Can anyone explain to m
Side-effect:
Think of a side-effect as something that does two things at once. For example:
Classic example of a side effect:
var i = 1;
var j = i++;
The side effect happens at i++. What happens here is j becomes 1 and then i gets incremented and becomes 2. In other words, two things happened and the side-effect was that i became 2.
Closure:
Visualize a chain of links like this: <><><><><><><>. Imagine that the name of this chain of links is called the scope chain. Then imagine that all these links connect objects together like this: <>object<>object<>object<>. Now, keep in mind the following:
(1) All scope chains begin with the global object.
(2) When a function is defined, a scope chain for that function is stored.
(3) When a function is invoked, it creates a new object and adds that to the scope chain.
Now, please look at the following example:
function counter () { // define counter
var count = 0;
return function () { return count + 1;}; // define anonymous function
};
var count = counter(); // invoke counter
In this example, when counter() is defined, the scope chain for counter looks like this: <>global object<>. Then, when counter() is invoked, the scope chain looks like this: <>global object<>counter object<>. After that, the function with no name (called an anonymous function) inside counter is defined and invoked. The scope chain for the anonymous function once invoked looks like this: <>global object<>counter object<>anonymous function object<>
Heres were the closure part comes in. If you notice, the anonymous function is using the variable count which was defined outside of it. The reason is because the anonymous function can access any variables defined in its scope chain. This is what a closure is, a function along with references to any variables in its stored scope chain.
However, in the above example, once the functions return, the objects created at invocation are discarded so there really is no point. Now look at the following:
function counter () { // define counter
var count = 0;
function f() { return count + 1;}; // define f
return f; // return f
};
var count = counter(); // invoke counter
In this example, I am returning a function named f and assign that to the variable count. Now the variable count holds a reference to the entire scope chain and it does not get discarded. In other words the variable count stores the scope chain like this: <>global object<>counter object<>anonymous function object<>. This is the power of closures, you can hold a reference to a scope chain, and call it like this: count().