Scoping in JavaScript
Tags: webdev, javascript, beginners
Published: 2023-04-26 13:33:21

When coding in JavaScript, tracking the scope of your variables and functions are critical to being able to write clear, concise and re-usable code. Scope refers to the rules in JavaScript that determine when and where variables and functions are accessible within your code. There are three main types of scoping in JavaScript; global scope, function scope and block scope.

**Global Scope**

When writing in JavaScript, any variable or function declared outside of a function or block of code is said to be “in global scope.” This means that it can be accessed, or “called”, from anywhere within the code for functions or anywhere after the variable declaration for variables. This difference is because functions are “hoisted”, or available in any part of the code as a result of the way JavaScript executes code. Because of this general availability at any time in your code, it may seem that global scope is the answer for every variable or function, however scoping every variable and function in global scope can lead to issues with recurrent variable or function names and ultimately make code harder to read and maintain. Because of this, it is usually advantageous to attempt to scope functions and variables to the parts of the code where they are needed to avoid conflicts within your code.
```
const apple = document.getElementById('apple')
function logApple(){
    console.log(apple)
}
```
The variable "_apple_" is available to the function _logApple()_ because both are declared in global scope. This means that the variable "_apple_" can be accessed anywhere in the script after the variable declaration. Because of this fact, the variable "_apple_" does not need to be passed to the function _logApple()_ as it already has access to the variable declared in global scope.

**Function Scope**

Because of the conflict issue with global scope, function scope is often used to preserve the functionality of code while reducing the possibility of naming conflicts or unintended code execution. Variables or functions initialized within the body of a function are said to be in “function scope” and are only accessible to the function they are declared within, as well as any nested functions beneath the original function. Declaring variables and nested functions this way is ideal because it can help avoid naming conflicts. If two variables exist within a single JavaScript document with the same name but are declared within different functions then no naming conflict error occurs. 

A function scoped variable is created in memory when the function is executed, and subsequently destroyed upon completion of that function. Therefore, two functions can exist and run within the same script, both declare identically named variables with different values, and not conflict. Though function scope allows for generally cleaner code and better organization through simpler naming conventions, using variables in this scope means that in order to access them within other functions we must pass them as arguments. Sometimes, this can make it difficult to follow where a variable originates or where the current value of that variable is assigned, or even cause hard to catch errors when you forget to pass a variable to a function that requires it!
```
function logApple(){
    const apple = document.getElementById('apple')
    console.log(apple)
}
console.log(apple)
```
In this example, the variable "_apple_" is declared in function scope, or within the body of the function _logApple()_. As a result, the variable apple is available to the _console.log()_ within the function, however it is not available to the _console.log()_ outside of the function, which will cause an error. 

**Block Scope**

Block scope is a relatively new introduction to JavaScript, as it is an additional functionality added to the language alongside the let and const keywords. Where previously variables were only ever declared with the var keyword, and when declared outside of a function were always in global scope, variables declared with let or const are able to be confined to a “block”. This is accomplished by simply enclosing the code which you wish to be inside of the block in a set of curly braces({}). This announces to JavaScript that the code within is a “block”, and therefore any variables declared with let or const will only be accessible within that block. This can be useful when writing larger scripts where there may be naming conflicts, and also making your code more modular and easier to update.
```
{
    const apple = document.getElementById('apple')
    function logApple(){
        console.log(apple)
    }
}
console.log(apple)
```
The code inside the block in this example is identical to the code in the first example and will work the same way. The variable "_apple_" is available to the function _logApple()_ because they are both declared within the same block of code. The _console.log()_ outside of the block will throw an error because it cannot access a variable declared within a block using _let _or _const_.

Ultimately, scoping is a core concept to JavaScript as a whole. Having a clear understanding of the uses and unintended effects of global scope and function scope, and the knowledge of how and when to utilize block scope is critical when attempting to write clear, clean, organized and maintainable code. Through proper application of all three types of scope, you’ll be able to write code with great naming conventions and no collisions, keep everything well organized, and make your code easier for yourself and others to read, understand, update and adapt!