Wednesday, February 26, 2014

Scope in JavaScript

Scope in JavaScript can be difficult to understand if you come from a block scoping language like C# or Java, but a few simple examples can make sense of it. This is a very simplistic explanation and glosses over the how and why, but does give good examples of the behavior to expect.

Braces do not determine scope in JavaScript, function definitions do.

function someFunction() {
    var a = 1;
    //prints 1
    console.log(a);
}
someFunction();
//undefined exception
console.log(a);

As you can see, a is visible within the function, but not outside.

function someFunction() {
    if (true) {
        var a = 1;
    }
    //prints 1
    console.log(a);
}
someFunction();
//undefined exception
console.log(a);

In the above snippet, b is visible outside the scope of the if statement, but is still visible within the function declaration, but not outside of the function.

Variables declared outside functions are visible from within.

//declare in global scope
var a = 1;
function someFunction() {
    //print 1
    console.log(a);   
}
someFunction();
//also prints 1
console.log(a);

Variable references can travel up the function chain as far as needed to find the declaration.

var a = 1;
function someFunction1() {
    function someFunction2() {
        //prints 1
        console.log(a);
    }
    someFunction2();
}
someFunction1();

But cannot travel back down the function chain at any step.

function someFunction1() {
    var a = 1;
    //prints 1
    console.log(a);
}
function someFunction2() {
    var b = 1;
    //prints 1
    console.log(b);
    //undefined exception
    console.log(a);
}
//undefined exception
console.log(a);
//undefined exception
console.log(b);

If two variables in the chain are declared and named the same, they both exist and are visible within their own scope.

//declared globally
var a = 1;
function someFunction() {
    //declared locally
    var a = 2;
    //prints 2 from local variable
    console.log(a);
}
someFunction();
//prints 1 from global variable
console.log(a);

If two variables are declared and named the same in the same scope, the second overwrites the first.

function someFunction() {
    var a = 1;
    //prints 1
    console.log(a);
    var a = 2;
    //prints 2
    console.log(a);
}
someFunction();

No matter where a variable is declared, if it is declared without the var keyword, it is scoped globally.

function someFunction() {
    a = 1;
    //prints 1
    console.log(a);
}
someFunction();
//prints 1
console.log(a);

Passed parameters are local in scope

function someFunction(a) {
    //prints 1
    console.log(a);
}
someFunction(1);
//undefined exception
console.log(a);

Passed parameters are still available in the chain

function someFunction(a) {
    function someFunction2() {
        //prints 4
        console.log(a);
    }
    someFunction2();
}
someFunction(4);

No comments:

Post a Comment