DEV Community

Cover image for JavaScript Basics-  Scopes & Hoisting
Debarshi Bhattacharjee
Debarshi Bhattacharjee

Posted on • Updated on

JavaScript Basics- Scopes & Hoisting

If you're a JS beginner, you must have heard these words.

Let's get in depth to understand more about these concepts in JS.

What is a Scope in JS?

A scope in JS is a context in which values and expressions are visible or can be referenced.
In simple words, Scope is the accessibility of variables, functions, and objects in some particular part of your code during runtime.

Types of scopes in JS:

JavaScript has 3 types of scopes :

  • Global Scope : Any variable, function, expression that is present globally or not declared inside any other function belongs to the global scope. Variables, functions that declared in global scope can accessed from anywhere in the program.
var foo=23; // declared in the global scope

function greet(){
console.log(foo);
} 

greet();// Prints '23'
console.log(foo)l //Prints '23'
Enter fullscreen mode Exit fullscreen mode
  • Local or Function Scope : Variables and functions that are enclosed in some other function become part of that function's local or function Scope. In other words, a local scope or function scope is associated with a function, when we declare variables and functions inside another function, they become part of the local/function scope and are restricted to that scope. Variables and function declared in function/local scope are accessible within that scope.
//Declared in Global Scope
var foo=23;

function bar(){ 
// Function or Local Scope
   var message="Hello JavaScript"; // inside the local/function 
                                   scope of bar 
   console.log(message); // Prints 'Hello JavaScript' 
   console.log(foo); // Prints '23'
}

//Global Scope
console.log(message); // Uncaught ReferenceError: message is not 
                         defined

Enter fullscreen mode Exit fullscreen mode
  • Block Scope : Variables declared with let and const can block scoped. That is, they can be enclosed within a pair of curly braces(blocks). Any variable/function declared with let or const, inside a pair of curly braces are only available within the scope of the braces. It stands true for only for variables that declared with let and const and not with var.
{ //Block scope
  let message = 'Hello JavaScript'; // declared with let
  var name = 'Debarshi'; // declared with var
  console.log(message); // Prints 'Hello JavaScript'
}

//Global scope
console.log(name);// prints 'Debarshi'
console.log(message); // Uncaught ReferenceError: message is not 
                         defined
Enter fullscreen mode Exit fullscreen mode

Hoisting in JS:

In JavaScript, hoisting is a concept in which a function or a variable can be used before declaration.

Hoisting with variables and functions declared with var keyword.

Variables declared with var keyword gets hoisted to the top of the scope. If accessed before initialization they result undefined.

console.log(baz); // Prints 'undefined'

console.log(greet); // Prints 'undefined

greet(); // Prints 'TypeError: greet is not a function'

var baz="Hello World!";

//anonymous function stored in a variable
var greet=function(){
    console.log("Hello JavaScript!");
}

greet(); // Prints 'Hello from JavaScript!'
Enter fullscreen mode Exit fullscreen mode

Hoisting with variables and functions declared/assigned with let and const keyword

Although variables and functions declared/assigned to let and const are also hoisted, but they cannot be accessed until they have been initialized.

console.log(a); // Prints 'ReferenceError: Cannot access 'a' 
                    before initialization'
console.log(name); // Prints 'ReferenceError: Cannot access 'm' 
                       before initialization'

doSomething(); // Prints 'ReferenceError: Cannot access 'm' before 
                   initialization' 

let a = 45; // Initialized
const name="Debarshi"; // Initialized

const doSomething = function (){
   console.log("Hello World!")
}

console.log(a) // Prints '45'

console.log(name) // Prints 'Debarshi'

doSomething(); // Prints 'Hello World!'
Enter fullscreen mode Exit fullscreen mode

Hoisting with functions:

  • Functions declared with function keyword:
    Functions that are declared with the function keyword
    are also hoisted and can accessed from the top of the scope.

       foo(); // Prints 'Hello from foo!'
    
       function foo(){
          console.log("Hello from foo!");
        } 
    
  • Anonymous functions, functions expression:

    As anonymous functions and function expressions are
    assigned/stored to a variable, they behave same as
    that of the variable depending on the variable type they
    are assigned to
    .

       baz(); // TypeError: baz is not a function
       foo();  // Uncaught ReferenceError: Cannot access 'foo' 
                  before initialization
    
       var baz=function(){ // assigned to var
       console.log("Hello from Baz");
       }
    
      let foo=()=>{  assigned to let
       console.log("Hello from Foo");
      }
    
      baz(); // Prints 'Hello from Baz'
      foo(); // Prints 'Hello from Foo'
    

Temporal Dead Zone in JS:

let and const variables cannot be read/written until they
have been fully initialized, which happens when they are
declared (if no initial value is specified on declaration,
the variable is initialized with a value of undefined).
Accessing the variable before the initialization results in
a ReferenceError.

  { // TDZ starts at beginning of scope
console.log(bar); // undefined
console.log(foo); // ReferenceError
var bar = 1;
let foo = 2; // End of TDZ (for foo)
}
Enter fullscreen mode Exit fullscreen mode




References:

MDN

Top comments (2)

Collapse
 
jonrandy profile image
Jon Randy ๐ŸŽ–๏ธ

The happens as the JavaScript compiler moves all the declarations of variables and functions at the top of the scope

This is actually not true, but is a convenient mental visualisation

Collapse
 
devdebarshi profile image
Debarshi Bhattacharjee

Yup true. Many things go behind this. Added this, for easy understanding.