You Don't Know JS: Book 2 (Scope and Closure) - 03 The Scope Chain
The scope chain, shadowing, and the different function forms.
The Scope Chain permalink
- the connections between scopes that are nested within other scopes
- It determines the path along which variables can be accessed.
- The chain is directed, meaning the lookup moves upward/outward only.
- When a function (declaration or expression) is defined, a new scope is created.
Lookups permalink
- The information of what scope a variable originates from is usually determined during the initial compilation processing.
- This information is immutable and is likely to be stored with (or at least accessible from) each variable's entry in the AST.
- Avoiding the need for a runtime lookup is a key optimization benefit of lexical scope.
Shadowing permalink
- when you have two or more variables, each in different scopes, with the same lexical names
- this prevents access to the outer variable from that point inward.
var studentName = "Suzy";
// the parameter is shadowing the (shadowed) global variable.
function printStudent(studentName) {
studentName = studentName.toUpperCase();
console.log(studentName);
}
printStudent("Frank");
// FRANK
printStudent(studentName);
// SUZY
console.log(studentName);
// Suzy
- Not all combinations of declaration shadowing are allowed.
let
can shadowvar
, butvar
cannot shadowlet
.
Global Unshadowing Trick permalink
- is accessing the shadowed variable through the global (
window
) object - when declared withvar
orfunction
var studentName = "Suzy";
function printStudent(studentName) {
console.log(studentName);
console.log(window.studentName);
}
printStudent("Frank");
// "Frank"
// "Suzy"
Function Name Scope permalink
- function declaration hoists, function expressions (a function definition used as value instead of a standalone declaration), does not
But what is the difference in the name?
// a named function expression
var askQuestion = function ofTheTeacher(){
// ..
};
// ofTheTeacher is declared as an identifier inside the function itself
var askQuestion = function ofTheTeacher() {
console.log(ofTheTeacher);
};
askQuestion();
// function ofTheTeacher()...
console.log(ofTheTeacher);
// ReferenceError: ofTheTeacher is not defined
// defined as read-only
var askQuestion = function ofTheTeacher() {
"use strict";
ofTheTeacher = 42; // TypeError
//..
};
askQuestion();
//
Arrow Functions permalink
- Arrow functions are lexically anonymous, meaning they have no directly related identifier that references the function.
// an inferred name
var askQuestion = () => {
// ..
};
askQuestion.name; // askQuestion