JavaScript variable scope

Tyler Tyler (258)
0

A scope is simply the set of variables that you have access to. Scoping in JavaScript can be confusing. Even some experienced JavaScript developers still struggle with it. Many people, including myself, have learned scoping the hard way. This guide aims to simplify JavaScript scoping.

Posted in these interests:

code
PRIMARY
86 subscribers
javascript
51 subscribers

The easiest way to understand scope is to think about what scope means. A scope is some device that you look through, think microscope or telescope. The word scope is derived from Greek words meaning to look out , target, or aim. A scope on a rifle is a great example. You look through the scope to focus in on something specific. The scope naturally blocks out things you are not trying to focus on. In programming, scope is very similar. Scope refers to some portion of code that you are focusing on. In JavaScript, there is a large scope, called global, and much smaller ones, called local scopes. Throughout this guide we will understand how these scopes are defined.

A globally scoped variable is any variable declared outside of a function. By default, in the context of a web browser, these global variables are added to the window object and can be accessed either directly by name or as an attribute of window, like this:

var x = 2;
alert(x);
// or
alert(window.x);
You can also declare a global variable within a function so long as you don't use the var keyword, like this:
function setSomeVar(x) {
    someVar = x;
}
setSomeVar(2);
alert(someVar);
As you'll see in later steps, using the var keyword to declare a variable gives that variable a local scope. However, if you don't use the var keyword, the interpreter will search up the scope chain until it finds a variable with the same name. That means, if you've declared a variable in an outer scope and reference that variable by name without using the var keyword from an inner scope, you will be referring to the outer variable. If no variable with the same name exists, your variable will be created in the global scope.

A locally scoped variable is a variable declared with the keyword var within a function. Local refers to the context of the function itself. When you declare a variable within a function it is made available throughout the entire function, and it is completely unavailable outside of the function. For example:

var x = 1;
function hello() {
    alert(x);
    var y = 2;
}
hello();
alert(y);
If you run this code you will find that the function hello has access to x because it is a global variable, but when we try to alert y outside of the function we get an Uncaught ReferenceError. That's because y is only available within the scope it was created. It is also important to note that parameters passed into a function are scoped locally. So in the following example:
function sendMessage(message) {
    alert(message);
}
sendMessage('hello, friend');
console.log(message);
we see the alert but get another Uncaught ReferenceError because the message variable is declared as a parameter of the function sendMessage and is only available from within the function itself. As JavaScript allows for nesting functions, a variable declared within a function is also available within its nested functions. Take this for example:
function go() {
    var x = 2;
    function add3() {
        return x + 3;
    }
    return add3();
}
alert(go());
You would never write this, but if you did you would find that x is available from within the add3 function. But as you might now assume, a local variable declared within a nested function is not available to its parent function. Keep in mind that in JavaScript, unlike many other programming languages, there is no block level scope. Instead JavaScript uses function level scoping.

JavaScript uses function level scope, not block level scope. What does this mean? A block generally refers to curly braces. So think conditions (if/else, switch) or loops (for, while). That means that each of these blocks do not get their own scope. Any variable declared from within a block will be available outside of the block as well. Take this for loop as an example:

for (var i = 0; i <= 10; i++) {
   console.log(i);
}
console.log('after', i); // prints "after 11" to the console
You'll see that the variable i is available outside of the for loop block. This is expected as there is no block level scoping. If this for loop isn't contained within a function, i will technically be a global variable. Otherwise it will be local to the function that contains it.