Logo
READLEARNKNOWCONNECT
Back to Lessons

    Page

  • - What Is Scope?
  • - Global Scope
  • - Function Scope
  • - Block Scope
  • - Lexical Scope
  • - What Is Hoisting?
  • - Hoisting with let and const
  • - Function Hoisting
  • - Mini Challenge
  • - Key Takeaway

8. Scope and Hoisting

Level: BeginnerDuration: 16m

What Is Scope?

Scope defines **where** a variable or function can be accessed in your code. It’s like the visibility range — some variables are global, others only exist inside functions or blocks.

Global Scope

A variable declared **outside any function or block** is in the global scope. It can be accessed anywhere in your code.

javascript
let siteName = "VeryCodedly";

function showName() {
  console.log(siteName); // Accessible here
}

showName();
console.log(siteName); // Accessible here too

Function Scope

Variables declared **inside a function** are only accessible inside that function. They’re private to that function’s code block.

javascript
function greet() {
  let message = "Hello!";
  console.log(message);
}

greet();
console.log(message); // ❌ Error: message is not defined

Here, `message` only exists inside `greet()`. Trying to access it outside causes an error.

Block Scope

Variables declared with `let` or `const` are block-scoped — meaning they only exist inside `{}` braces (like loops or if statements).

javascript
if (true) {
  let color = "mint";
  console.log(color); // ✅ Works here
}

console.log(color); // ❌ Error: color is not defined

`var`, on the other hand, ignores block scope — it’s function-scoped, not block-scoped. That’s one reason developers prefer `let` and `const`.

Lexical Scope

Functions in JavaScript can access variables from where they were **defined**, not where they’re **called**. This is called **lexical scope**.

javascript
function outer() {
  let name = "Nia";

  function inner() {
    console.log(name); // ✅ Can access parent’s variable
  }

  inner();
}

outer();

What Is Hoisting?

Hoisting means that JavaScript moves variable and function declarations to the top of their scope **before code runs**. It doesn’t move values — just the declarations.

javascript
console.log(name); // undefined
var name = "Ada";

Because of hoisting, the declaration of `name` is moved up, but not the assignment. It’s as if JavaScript rewrote it like this:

javascript
var name;
console.log(name); // undefined
name = "Ada";

Hoisting with let and const

`let` and `const` are also hoisted — but they’re placed in a **temporal dead zone (TDZ)** until their declaration is reached. Accessing them early causes an error.

javascript
console.log(food); // ❌ ReferenceError
let food = "Jollof";

Function Hoisting

Function declarations are fully hoisted — you can call them before they appear in the code.

javascript
sayHi(); // ✅ Works fine

function sayHi() {
  console.log("Hey there!");
}

However, **function expressions** and **arrow functions** are not hoisted the same way, so calling them before they’re defined will cause an error.

javascript
sayBye(); // ❌ Error

const sayBye = () => {
  console.log("Goodbye!");
};

Mini Challenge

1. Try declaring a variable with `var`, `let`, and `const` inside an `if` block. 2. See which ones are accessible outside the block. 3. Then test what happens when you call a function before its declaration.

Key Takeaway

Scope defines where variables live. Hoisting defines when they come to life. Mastering both helps you avoid mysterious 'undefined' and 'not defined' errors.

MDN Docs: Scope and Hoisting