Scope and Where Variables Exist

Course: JavaScript Intermediate

Lesson 1: Scope and Where Variables Exist

Level

Intermediate

Estimated Reading Time

10–15 minutes

Goal

By the end of this lesson, the learner will be able to:

  • Explain the difference between block scope, function scope, and global scope
  • Use const and let correctly within blocks and functions
  • Identify when a variable is accessible and when it causes a ReferenceError

Frontend Development Context

In frontend development, variable scope determines which parts of your code can read or modify a value. When you write a click handler, a loop, or a conditional block, the variables you declare inside those structures are not always available outside them. Understanding scope helps you avoid bugs where a variable seems to disappear or holds an unexpected value.

Scope also affects how you organize code into functions and modules. A variable declared at the top of a file is globally scoped and accessible everywhere — which can be convenient but also dangerous if multiple parts of the app modify it. Keeping variables scoped as narrowly as possible is a core discipline in writing maintainable JavaScript.

Explanation

JavaScript has three main levels of scope: global, function, and block. A variable declared outside any function or block lives in global scope and can be accessed anywhere in the script. A variable declared inside a function is scoped to that function and cannot be accessed outside it. A variable declared inside a block — any pair of curly braces {} — using let or const is scoped to that block only.

The var keyword behaves differently from let and const. Variables declared with var are function-scoped, not block-scoped. This means a var declared inside an if block leaks out to the surrounding function, which is rarely what you want. This is one reason var is avoided in modern JavaScript.

const and let respect block boundaries. If you declare const score = 0 inside an if block, that variable does not exist before the block starts or after it ends. Trying to access it outside the block produces a ReferenceError.

Function scope creates a new isolated environment. Variables declared inside a function are local to that function. They are created when the function runs and destroyed when it finishes. This allows you to reuse variable names like i or result in different functions without conflicts.

Nested scopes follow a chain: inner scopes can read variables from outer scopes, but outer scopes cannot access variables from inner scopes. This lookup chain is called the scope chain, and understanding it helps you reason about which value a variable holds at any point in your code.

Code Example

This example shows global scope, function scope, and block scope in action side by side.

const appName = "LearnSkills"; // global scope

function showLessonInfo(lessonTitle) {
  const prefix = "Lesson:"; // function scope

  if (lessonTitle) {
    const message = `${prefix} ${lessonTitle} — ${appName}`; // block scope
    console.log(message); // works fine here
  }

  // console.log(message); // ReferenceError: message is not defined
  console.log(prefix); // works — still inside the function
}

showLessonInfo("Scope Basics");
// console.log(prefix); // ReferenceError: prefix is not defined
console.log(appName);   // works — global scope

Code Explanation

appName is declared at the top level outside any function or block, making it globally scoped. Both the function body and the if block can read it freely because inner scopes can look outward along the scope chain.

prefix is declared inside showLessonInfo. It is function-scoped — accessible anywhere inside that function but not outside it. Attempting to log prefix after the function call would throw a ReferenceError.

message is declared with const inside the if block. It only exists within those curly braces. The commented-out line shows what would happen if you tried to access it after the block closes — the variable no longer exists at that point.

This layered structure illustrates how JavaScript resolves variable names by looking outward: the if block can see prefix and appName, but nothing outside can see message or prefix.

Pattern Highlights

Positive Pattern: Declare variables with const or let as close to where they are used as possible. This limits their scope and makes code easier to reason about.

⚠️ Neutral Note: Inner scopes can read variables from outer scopes. This is useful but can make code harder to trace if overused — keep outer variables focused and clearly named.

Negative Pattern: Avoid using var inside blocks expecting block-scoping behavior. A var declared inside an if block is still accessible in the surrounding function, which leads to subtle bugs.

Common Mistakes

Mistake 1: Using var inside a block and expecting it to be block-scoped

Developers coming from other languages often expect var to behave like let.

if (true) {
  var count = 5;
}
console.log(count); // 5 — unexpected! var is not block-scoped

Because var is function-scoped (or globally scoped when outside a function), it leaks out of the if block. Use let or const instead.

Mistake 2: Accessing a const or let variable before its declaration line

Assuming a variable exists just because it appears somewhere in the function.

function setup() {
  console.log(label); // ReferenceError: Cannot access 'label' before initialization
  const label = "Active";
}
setup();

const and let variables are not accessible before their declaration. This is the temporal dead zone. Always declare before you use.

Mistake 3: Shadowing an outer variable unintentionally

Declaring a new variable with the same name in an inner scope hides the outer one.

const status = "online";

function checkStatus() {
  const status = "offline"; // shadows outer status
  console.log(status);      // "offline"
}

checkStatus();
console.log(status); // "online" — outer is unchanged, but the shadowing is confusing

While shadowing is not an error, it makes code harder to read. Use distinct names to avoid confusion.

Quick Recap

  • Global scope means a variable is accessible everywhere in the script
  • Function scope means a variable only exists inside the function that declares it
  • Block scope with const or let means a variable only exists inside the {} block that contains it
  • var is function-scoped and leaks out of blocks — prefer const and let in all modern code

Ready to test your understanding? Take the quiz to reinforce what you learned.

© 2026 Ant Skillsv.26.07.07-23:01