Last updated on 2015-12-08

Previous Tutorial: Variables, Functions, and Objects

Naming is one of the hardest problems in programming. Since there are many things to decide when creating a program, programmers tend to use the same name for variables in many places. And because JavaScript is a very “promiscuous” language, this can cause serious bugs that can be very hard to debug. Therefore it is very important to know what is the scope of the variables we define in our program:

### Global Scope

These are variables that you declare outside functions or objects with or without the `var` keyword, or variables declared inside functions without the `var` keyword. Let’s look at an example:

```a = 1;
b = 2
var c = 3;
console.info("a=" + a + ", b=" + b + ", c=" + c); // prints "a=1, b=2, c=3"
function foo() {
a = 6;
var b = 7
var c = 5;
d = 8;
console.info("a=" + a + ", b=" + b + ", c=" + c+", d="+d); // prints "a=6, b=7, c=5, d=8"
}
foo();
console.info("a=" + a + ", b=" + b + ", c=" + c + ", d=" + d); // prints "a=6, b=2, c=3, d=8"
```

We can see that setting the value of the global variable `a` inside function `foo` sets the value also outside the function. This can be prevented by using the `var` keyword, as done with variable `b`. Variable `c` behaves as expected as it is declared both globally and locally (a.k.a masking), therefore changes to the variable are only local. Lastly, variable `d` is defined inside function `foo` without the `var` declaration, therefore becomes a new global variable after the function is invoked.

### Function Scope

Variables declared (with the `var` keyword) inside a function (or an object constructor which is also a function) are scoped to the function and all functions defined inside this function (JavaScript allows us to define functions inside functions, as we will see below). But there are some gotchas that need some investigating. Let’s have an example:

```var a = 1;
var b = 2;
var c;
console.info("a=" + a + ", b=" + b+", c="+c); // prints "a=1, b=2, c=undefined"
function foo() {
var a = 3;
var c = 4;
console.info("a=" + a + ", b=" + b + ", c=" + c); // prints "a=3, b=undefined, c=4"
function bar() {
var a = 5;
c = 6;
console.info("a=" + a + ", b=" + b + ", c=" + c); // prints "a=5, b=7, c=6"
}
var b = 7;
bar();
console.info("a=" + a + ", b=" + b + ", c=" + c); // prints "a=3, b=7, c=6"
}
foo();
console.info("a=" + a + ", b=" + b + ", c=" + c); // prints "a=1, b=2, c=undefined"
```

We first define 3 global variables to use in our example. Note that `c` has been defined but not yet given a value, so the output of our first print statement show it as “undefined” (yea, very confusing that a defined variable is called “undefined” instead of “uninitialized”… Someone is laughing at us here).

Now comes the interesting stuff. When `foo` is invoked, variables `a` and `c` are redefined, masking the global variables, but when we print their value, we also get `b=undefined`. Wat?. What is happening here is that a few lines below we defined `b` giving it the value `7`. When a function is called, the JavaScript interpreter scans for all variable definitions inside the function and creates for them a variable that is undefined, and then executes the function. Weird, and definitely something to remember.

Moving forward, function `bar` is defined and executed, with `a` masking the local `a` from `foo`, and the assignment of `6` to `c` which changes the variable from the closing scope (`foo`). At the end of the example, we cab see that all variables in the global scope are unchanged, because we masked them inside the functions.

### Closures

A closure is a way to tie a function with variables outside of its scope. The closure of a function contains all of the variables that are not defined inside the function and used by it (and are not global). Since JavaScript allows for the definition of variables inside functions, it is very easy to show how this works:

```function foo(x) {
var a = x;
return function () {
a = a + 5;
return a;
}
}
var bar1 = foo(10);
console.info("a=" + bar1()); // prints "a=15"
var = foo(100);
console.info("a=" + bar2()); // prints "a=105"
console.info("a=" + bar1()); // prints "a=20"
console.info("a=" + bar2()); // prints "a=110"
```

We defined function `foo` which returns a function (cool, right?). This internal function uses the value of `a` defined in the enclosing scope, creating a closure. When we invoke `bar`, the value of `a` is already defined an matches the value of the parameter passed to `foo`. Furthermore, you can see from the output that each time `foo` is called, a new closure is created with a new value of `a`.

Awesome.

Next Tutorial: Object Creation and Prototype Chains

Published inProgramming

## Be First to Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.