Storing values in variables is a fundamental concept in programming. A variable’s “scope” determines when it is and isn’t available throughout your program. Understanding variable scope in JavaScript is one of the keys to building a solid foundation in the language. Show
This article will explain how JavaScript’s scoping system works. You’ll learn about the different ways to declare variables, the differences between local scope and global scope, and about something called “hoisting” — a JavaScript quirk that can turn an innocent-looking variable declaration into a subtle bug. Variable ScopeIn JavaScript, the scope of a variable is controlled by the location of the variable declaration, and it defines the part of the program where a particular variable is accessible. Currently, there are three ways to declare a variable in
JavaScript: by using the old Scoping rules vary from language to language. JavaScript has two scopes: global and local. Local scope has two variations: the old function scope, and the new block scope introduced with ES6. It’s worth noting that function scope is actually a special type of a block scope. Global ScopeIn a script, the outermost scope is the global scope. Any variables declared in this scope become global variables and are accessible from anywhere in the program:
As this simple example shows, the variable But as handy as this might seem, the use of global variables is discouraged in JavaScript. This is, for example, because they can potentially be overwritten by other scripts, or from elsewhere in your program. Local ScopeAny variables declared inside a block belong to that particular block and become local variables. A function in JavaScript defines a scope for variables declared using A code block ( The
Function and block scopes can be nested. In such a situation, with multiple nested scopes, a variable is accessible within its own scope or from inner scope. But outside of its scope, the variable is inaccessible. A Simple Example to Help Visualize ScopeTo make things clear, let’s use a simple metaphor. Every country in our world has frontiers. Everything inside these frontiers belongs to the country’s scope. In every country there are many cities, and each one of them has its own city’s scope. The countries and cities are just like JavaScript functions or blocks. They have their local scopes. The same is true for the continents. Although they are huge in size, they also can be defined as locales. On the other hand, the world’s oceans can’t be defined as having local scope, because they actually wrap all local objects — continents, countries, and cities — and thus, their scope is defined as global. Let’s visualize this in the next example:
See the Pen Here, the Now that we understand what local and global scopes are, and how they’re created, it’s time to learn how the JavaScript interpreter uses them to find a particular variable. Back to the given metaphor, let’s say I want to find a friend of mine whose name is Monique. I know that she lives in Paris, so I start my searching from there. When I can’t find her in Paris, I go one level up and expand my searching in all of France. But again, she’s not there. Next, I expand my searching again by going another level up. Finally, I find her in Italy, which in our case is the local scope of Europe. In the previous example, my friend Monique is
represented by the variable This type of lookup is called lexical (static) scope. The static structure of a program determines the variable scope. The scope of a variable is defined by its location within the source code, and nested functions have access to variables declared in their outer scope. No matter where a function is called from, or even how it’s called, its lexical scope depends only on where the function was declared. Now let’s see how the new block scope works:
See the Pen In this example, we can see that the Let’s now replace the
See the Pen As you can see, when we use the In JavaScript, variables with the same name can be specified at multiple layers of nested scope. In such a situation, local variables gain priority over global variables. If you declare a local variable and a global variable with the same name, the local variable will take precedence when you use it inside a function or block. This type of behavior is called shadowing. Simply put, the inner variable shadows the outer. That’s the exact mechanism used when a JavaScript interpreter is trying to find a particular variable. It starts at the innermost scope being executed at the time, and continues until the first match is found, no matter whether there are other variables with the same name in the outer levels or not. Let’s see an example:
See the Pen Even with the same name, the local variable
doesn’t overwrite the global one after the execution of the
See the Pen This time, the local variable Note: in strict mode, it’s an error if you assign value to variable without first declaring the variable. HoistingA JavaScript interpreter performs many operations behind the scenes, and one of them is “hoisting”. If you’re not aware of this “hidden” behavior, it can cause a lot of confusion. The best way of thinking about the behavior of JavaScript variables is to always visualize them as consisting of two parts: a declaration and an initialization/assignment:
In the above code, we first declare the variable We already know that any variable declared within a scope belongs to that scope. But what we don’t know yet is that, no matter where variables are declared within a particular scope, all variable declarations are moved to the top of their scope (global or local). This is called hoisting, as the variable declarations are hoisted to the top of the scope. Note that hoisting only moves the declaration. Any assignments are left in place. Let’s see an example:
See the Pen As you can see, when we log the value of
It’s important to note that the variable is not physically moved. Hoisting is just a model describing what the JS engine does behind the scenes. Now, let’s see how hoisting works with
See the Pen In this example, the console output is not
See the Pen Variables declared with FunctionsHoisting also affects function declarations. But before we see some examples, let’s first learn the difference between a function declaration and function expression:
The easiest way to distinguish a function declaration from a function expression is to check the position of the word Function declarations are hoisted completely. This means that the entire function’s body is moved to the top. This allows you to call a function before it has been declared:
See the Pen The reason the preceding code works is that the JavaScript engine moves the declaration of the
As you may have noticed, only the function declaration is hoisted, but the function expression isn’t. When a function is assigned to a variable, the rules are the same as for variable hoisting (only the declaration is moved, while the assignment is left in place). In the code above, we saw that the function declaration takes precedence over the variable declaration. And in the next example, we’ll see that when we have a function declaration versus a variable assignment, the last takes priority:
See the Pen
This time, we call the
Note: arrow functions work identically to function expressions. ClassesClass declarations are also hoisted in a similar way as variables declared with
See the Pen
In this example, we can see that using the
See the Pen Classes can also be created using a class expression, by using
See the Pen In this example, we can see that the
See the Pen Things to Remember
Which variables can be accessible by that function only?What is a Local Variable? Variables that are declared within or inside a function block are known as Local variables. These variables can only be accessed within the function in which they are declared.
Which variable can be accessible by any function in the program?As the name suggests, Global Variables can be accessed from any part of the program.
When you declare a variable within a function is that variable only accessible within that function?On the other hand, if you declare a variable inside a function with the var keyword, the variable is only available within the function definition, and cannot be accessed outside of the function. We, therefore, say that variables declared with var are function-scoped.
Which variable can be accessed from outside the block of its declaration?Variables declared outside the function block and accessed inside the function are called global variables.
|