Skip to main content

JavaScript Scope & Hoisting

JavaScript Block Scope

Written by Published

JavaScript block scope means let and const variables only exist inside the braces where they were declared.

A block is any pair of braces: an if, a loop, or a plain pair on its own.

var ignores blocks entirely, which is the main reason it causes confusion.

Example

Example

javascript

if (true) {
  let message = "inside";
  console.log(message);
}

console.log(typeof message);

The variable exists inside the block.

Outside, it is undefined, because it does not exist there at all.

What is Block Scope?

A block is any section of code between braces.

let and const are limited to the block they are declared in.

var is not: it belongs to the whole function, no matter how deeply nested it is.

Syntax

Syntax

javascript

{
  let blockOnly = "here";
}

The braces alone are enough to create a new scope for let and const.

let and const in a Loop

Each turn of the loop gets its own copy of a let variable.

Example

Example

javascript

for (let i = 0; i < 3; i++) {
  // i is a new variable each turn
}

console.log(typeof i);

After the loop, i does not exist.

var Escapes the Block

A var declared inside a loop is still there afterwards.

It belongs to the surrounding function, not the loop.

Example

Example

javascript

function test() {
  for (var j = 0; j < 3; j++) {
    // j belongs to the function
  }

  return j;
}

console.log(test());

The function returns 3, because j survived the loop.

The Classic var Loop Bug

Because every turn shares one var, callbacks created in the loop all see the final value.

With let, each turn has its own variable and the problem disappears.

Example

Example

javascript

const results = [];

for (let i = 1; i <= 3; i++) {
  results.push(function () {
    return i;
  });
}

console.log(results[0]() + "," + results[1]() + "," + results[2]());

With let the output is 1,2,3.

With var it would be 4,4,4, because all three share one variable.

const Cannot Be Reassigned

const follows the same block rules as let.

The difference is that the variable itself cannot be pointed at something new.

Example

Example

javascript

const settings = { theme: "dark" };

settings.theme = "light";

console.log(settings.theme);

Changing a property is allowed.

Reassigning settings to a different object would be an error.

Blocks Inside if Statements

Declaring inside an if keeps the variable out of the rest of the function.

Example

Example

javascript

function check(score) {
  if (score > 50) {
    const grade = "Pass";
    return grade;
  }

  return "Fail";
}

console.log(check(70));

grade only exists in the branch that needs it.

Complete Example

Complete Example

html

<!DOCTYPE html>
<html>
<head>
  <title>JavaScript Block Scope</title>
</head>
<body>

  <h1>JavaScript Block Scope</h1>

  <p id="result"></p>

  <script>
    const results = [];

    for (let i = 1; i <= 3; i++) {
      results.push(function () {
        return i;
      });
    }

    document.getElementById("result").innerHTML =
      results[0]() + ", " + results[1]() + ", " + results[2]();
  </script>

</body>
</html>

Try It Yourself

Run the above example in the Try It Editor.

Try swapping let for var:

Change let i to var i and watch the output become 4, 4, 4.

Important Points

  • A block is any pair of braces.
  • let and const only exist inside their block.
  • var ignores blocks and belongs to the whole function.
  • Each turn of a let loop gets its own variable.
  • const stops reassignment, but object properties can still change.

Conclusion

JavaScript block scope keeps variables close to the code that uses them.

Using let and const avoids the loop bugs that var causes.

Understanding block scope is why modern code almost never uses var.