Q103: Scope Chain and Identifier Resolution
What Interviewers Want To Evaluate
This question tests whether you can explain how JavaScript finds variables and why some names shadow others. Interviewers want lexical scope, nested environments, shadowing, global scope, modules, strict mode, accidental globals, and the difference between scope chain and prototype chain.
Senior engineers should be able to debug name lookup issues without guessing.
Short Interview Answer
The scope chain is the chain of lexical environments JavaScript uses to resolve identifiers. When code reads a variable name, the engine checks the current lexical environment first, then each outer environment, and finally the global environment. Inner bindings can shadow outer bindings. If no binding is found, JavaScript throws a ReferenceError for reads. The scope chain is different from the prototype chain, which is used for object property lookup.
Detailed Interview Answer
Identifier resolution is the process of finding what a variable name refers to. JavaScript does this through lexical environments, not by searching every object in memory.
The lookup path is:
current lexical environment
outer lexical environment
next outer lexical environment
global lexical environment
not found -> ReferenceError
Shadowing
Shadowing happens when an inner scope declares a binding with the same name as an outer scope. The inner binding wins for code inside that scope.
Shadowing is legal but can reduce clarity when overused.
Global Scope
Global scope contains global bindings. In browsers, some global declarations also become properties on window, but modules and let or const behave differently from old script-style var.
Senior answers should avoid oversimplifying global scope as just “the window object.”
Modules
ES modules have module scope. Top-level declarations in a module do not automatically become global variables.
This is one reason modules reduce accidental global pollution.
Strict Mode
Strict mode prevents some unsafe behaviors. Assigning to an undeclared variable throws instead of creating an accidental global.
Modern modules are strict by default.
Scope Chain vs Prototype Chain
The scope chain resolves identifiers. The prototype chain resolves object properties.
const name = "scope";
const user = { name: "property" };
console.log(name); // identifier lookup
console.log(user.name); // property lookup
These are different algorithms.
Common Mistakes
A common mistake is saying JavaScript looks for variables on parent objects. Lexical variables are resolved through lexical environments.
Another mistake is confusing this.name with name. this.name is property access. name is identifier resolution.
Senior Trade-Offs
Shadowing can make short functions clear but can make large functions confusing. Global variables are convenient but create coupling and test difficulty.
A senior answer should connect scope clarity to maintainability.
Code or Design Example
const status = "global";
function outer() {
const status = "outer";
function inner() {
const status = "inner";
console.log(status);
}
inner();
}
outer(); // "inner"
The innermost binding shadows the outer bindings.
Production Example
A bug can happen when a module imports a helper named format, then a local function also declares format. The local binding shadows the imported one, causing different behavior than expected.
Code review should catch confusing shadowing in important logic.
Debugging Workflow
When a variable has an unexpected value:
find the nearest declaration
check for shadowing
check module imports
check block scope
check whether this is property access instead
check strict mode and accidental globals
Interview Framing
Use a simple nested function example, then explicitly distinguish identifier lookup from property lookup.
That distinction is a strong senior signal because many bugs come from confusing the two.
Revision Notes
Scope chain lookup walks lexical environments. Prototype chain lookup walks object prototypes.
Key Takeaways
Identifier resolution is lexical and predictable once you know the environment chain.
Follow-Up Questions
- What is the scope chain?
- How does identifier lookup work?
- What is variable shadowing?
- How does module scope differ from script scope?
- How does strict mode affect accidental globals?
- How is scope chain different from prototype chain?
- What is the difference between
nameandthis.name? - How do imports affect scope?
- Why can shadowing be dangerous?
- How do you debug unexpected variable values?
How I Would Answer This In A Real Interview
I would explain that JavaScript resolves identifiers by checking the current lexical environment and walking outward. Then I would cover shadowing, modules, strict mode, accidental globals, and clearly separate scope chain from prototype chain.