Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Asynchronous JavaScript  ›  Lesson

Lexical Scoping

Lexical Scoping 10 minA function's scope is fixed by where it is physically written in the code, not by where or how it gets called — it can always read the variables of every scope it was nested inside at the moment it was defined, and nothing outside can read inward.

Lexical Scoping

In short: a function's scope — which variables it can see — is fixed by where it is written in the code, permanently, the moment it's defined. It can read any variable from every scope it's nested inside at that point, no matter where it's later called from. This is different from asking "who called this function?" — lexical scoping only ever cares about "where does this function live on the page?"

Three nested rooms: announce() holds shopName, the room inside it holds item, and callOut() inside both reads shopName AND item — both outer walls are visible from inside; a note that scope is fixed by where a function is written, never by where it's called from

Reading labels from every room you're nested in

A function nested inside two others can see variables from both:

javascript

callOut is written inside announce, which is written alongside shopName. So callOut can read item (its immediate parent's variable) and shopName (the outer scope's) — both walls of the rooms it's nested in are visible from where it's standing.

The scope is set once, at definition, not at every call

Call a function many times, and its scope doesn't change — only the values inside that fixed scope can:

javascript

inner was written inside outer, so it can always read and change outer's count — that relationship is locked in by where inner sits in the code, not by anything about how outer() gets invoked.

Called from somewhere else entirely — the scope doesn't move

This is the part that separates lexical scoping from "whoever calls me":

javascript

greet was written inside makeGreeter, where greeting is "Hello". Passing greet into runElsewhere and calling it there doesn't change that — runElsewhere's own greeting is a completely different variable in a completely different scope, invisible to greet. The function "remembers" where it was born, not where it currently happens to be running.

Quick practice

quick drill

What determines a function's scope in JavaScript?

quick drill

In the makeGreeter/runElsewhere example, what does runElsewhere(greet) print?

quick drill

A function declared inside another function tries to read a variable declared OUTSIDE both of them, further up. Can it?

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainCalled from elsewhere, scoped where it was written

A function greet is defined inside makeGreeter, where greeting = "Hello". It's then returned and called later, inside a completely different function runElsewhere that has its own local greeting = "This should NOT be seen". Explain which greeting actually prints, and why — this is the core of lexical scoping.