JavaScript quirk 6: the scope of variables

[2013-05-15] dev, twelvequirks, javascript, jslang
(Ad, please don’t block)
[This post is part of a series on JavaScript quirks.]

In most programming languages, variables only exist within the block in which they have been declared. In JavaScript, they exist in the complete (innermost) surrounding function:

    function func(x) {
        console.log(tmp); // undefined
        if (x < 0) {
            var tmp = 100 - x;  // (*)
            ...
        }
    }
The cause of the above behavior is hoisting: Internally, the declaration at (*) is moved to the beginning of the function (the assignment stays where it is). That is, what a JavaScript engine actually executes looks like this:
    function func(x) {
        var tmp;
        console.log(tmp); // undefined
        if (x < 0) {
            tmp = 100 - x;
            ...
        }
    }
But there is a trick to limit the scope of a variable to a block, it is called Immediately Invoked Function Expression (IIFE, pronounced “iffy”). Below, we use an IIFE to restrict the scope of tmp to the then-block of the if statement.
    function func(x) {
        console.log(tmp); // ReferenceError: tmp is not defined
        if (x < 0) {
            (function () {  // open IIFE
                var tmp = 100 - x;
                ...
            }());  // close IIFE
        }
    }
We wrapped a function around the insides of the block, creating a new scope for them. Then we immediately called that function. tmp only exists inside the IIFE. Note that the parentheses at the beginning and the end of the IIFE are necessary. They lead to the function being interpreted as an expression, which is the only form in which it can be be immediately invoked.