Skip to main content

What is scope?

Scope is the set of rules that determines where a variable can be accessed. When you declare a variable, it’s only visible within a certain region of your code. Try to use it outside that region and you’ll get an error.
orderId exists inside processOrder and nowhere else. This is a good thing — it means variables don’t leak into places they shouldn’t be.
Python mental model: this is the same general idea as Python scope (LEGB: Local, Enclosing, Global, Built-in). The biggest difference you’ll feel in JavaScript is that let/const also create block scope for if/for/while.

Block scope

Variables declared with const and let are block-scoped. They exist only within the nearest set of curly braces {}.
Every if, for, while, and function body creates a new block scope:
This is a real difference from Python. In Python, if and for blocks don’t create their own scope — variables leak out. In JavaScript, they don’t.
If you’re used to Python, this will trip you up. Variables declared inside if, for, or while blocks in JavaScript are not accessible outside those blocks. This is actually safer — it prevents accidental name collisions.

Function scope

Functions create their own scope. Variables declared inside a function are invisible outside it.
Nested functions can access variables from their parent function:
This is called lexical scoping — inner functions can look “up” to their parent’s scope, but parents can’t look “down” into children.
This part is very similar to Python: nested functions can read variables from outer functions. That’s the foundation for closures in both languages.

Global scope

Variables declared outside any function or block are in the global scope. They’re accessible everywhere.
Keep global variables to a minimum. Use them for true constants like API URLs and configuration values. Everything else should live in the smallest scope possible.

Scope chain

When JavaScript encounters a variable, it searches from the current scope outward:
Each color is a different variable in a different scope. The inner-most scope wins. This is called variable shadowing.
Python mental model: same idea as name shadowing in nested scopes — a local variable named color hides an outer color. JavaScript’s scope chain and Python’s LEGB rule are solving the same problem.
Variable shadowing is legal but can be confusing. Avoid reusing the same variable name in nested scopes. ESLint can warn you about this with the no-shadow rule.

Common mistakes

If you need a variable after a block ends, declare it before the block with let. You can assign the value inside the block.
var has confusing hoisting behavior — it exists before its declaration but with the value undefined. This is one of the main reasons the JavaScript community moved to const and let. Stick with const and let and you’ll never deal with hoisting issues.

What’s next?

You understand how scope works — variables live inside blocks and functions, and inner scopes can see outer scopes. This leads directly to one of JavaScript’s most useful features: closures.

Closures

How functions remember their surrounding variables