Tutorial

Understanding Variable Scope in JavaScript

Published on October 1, 2019
Default avatar

By Julia Ihnatova

Understanding Variable Scope in JavaScript

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

The scope is the execution context of a variable or function. It defines what data it has access to. This concept may seem pretty straightforward, but has some important subtleties.

JavaScript has traditionally had two types of scope: global scope and local scope. The purpose of the scope is to provide access to all variables and functions that an execution context has access to.

Global Scope

When a variable is declared outside of any function it belongs to the global scope automatically and can be accessed from anywhere in the program, be it a function or any block. Also, if desired, in the browser we can create a global variable by declaring it as window.newVariable at any place in a program.

const nestAnimal = 'crocodilian';   // belongs to the Global scope

function getNestInfo(){
  window.eggs = 5;     // as well belongs to the Global scope
}

In fact, in the browser, variables in the global scope belong to the global window object.

JavaScript is a garbage-collected language, it keeps available all variables while executing the program in the context and remove after. Let’s consider the lifecycle of the variable. The variable comes into existence during the execution of the function. The variable is used inside the function and then the function ends. At that point this variable is no longer needed, so its memory can be reclaimed and JavaScript remove this variable from the memory. But global variables remain in the memory for the all the time the application is running and clogs up it, which slows down the program, also it may cause unexpected name conflicts.

That all means that, whenever possible, you should avoid to defining global variables. They are only truly needed in very specific cases, so be careful with this.

Local Scope

ES6 introduced block-scoped variables using the const and let keywords. With these keywords, local scope is created and exists within the innermost block that surrounds it. It could be a function, for loop, while block, if block, etc. Such locally scoped variables can be only accessed from within that block.

Each block has its own execution context which defines what data it has access to, as well as how it should behave. When code is executed in a context, a scope chain is created. It includes all declared variables and functions inside that block, then the data from the containing (parent) context, and so on. This pattern continue until the global context is reached.

Let’s have a look at an example:

let caymanMood = 'calm';

function changeMood(newMood){
  if (caymanMood === 'calm'){
    caymanMood = newMood;
  } else {
    caymanMood = 'calm';
  }
}

changeMood('happy');

The function changeMood has a scope chain with two objects in it: its own variable object (arguments object newMood) and the global context’s variable object caymanMood. The function has access to caymanMood because it’s part of its scope chain.

Scope Chain Augmentation

It’s possible to augment the scope chain besides global and local execution contexts. We can do this in two ways.

  • Point 1: A with statement
  • Point 2: The catch block in a try...catch statement.
function buildNest() {
  const assets = 'grass';
  with(reptilian){
    const building = ability + assets;
  }
  return building;
}

with creates a object that is added to the front of the scope chain, but the thing is when you read the code you can’t know for sure which object exactly will be modified. Will it be the global variable ability or the variable in this context reptilian.ability. So the correct execution of the program can’t be guaranteed. Use of the with statement is not recommended by the MDN web docs as it may be a source of confusing bugs and compatibility issues.

The catch statement creates a new variable object that contains a declaration for the thrown error object and this error object is added to the front of the scope chain.

Wrapping Up

With this, you should now have a slightly better understanding of how local and global scope works in JavaScript and how relying on the closest local context possible is a good idea for writing easily readable and maintainable code.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Julia Ihnatova

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel