Chapter 2: Illustrating Lexical Scope - hochan222/Everything-in-JavaScript GitHub Wiki
μ©μ΄ "lexical"λ μ»΄νμΌμ 첫 λ²μ§Έ λ¨κ³ (μ΄ν λΆμ/νμ±)μ μλ―Ένλ€.
Marbles, and Buckets, and Bubbles... Oh My!
κ° λ²μλ μμ λ²μμ ν¬ν¨λλ©° μ»΄νμΌ μ€μ κ²°μ λλ€.
μ ννλ studentID 맀κ°λ³μλ νλμ λ²μμ ν¬ν¨λμ§ μλλ€. (νμ§λ§ μ°μ λμ΄κ°μ! λ€μ λμ΄)
id, name, log λ λ³μκ° μλκ³ μμ±μ΄λ€.
JS μμ§μ λ³μ μ μΈμ μ°ΎμΌλ©΄ μμλ λ²μλ₯Ό μ§μνλ€. λ³μ/μλ³μμ λν μ°Έμ‘°λ μμ λ²μμμλ κ°λ₯νμ§λ§ νμ λ²μμμλ λΆκ°λ₯νλ€.
"shadows" scopeμ μνμ§ μλ ν μ λ²μ κ·μΉμ λ°λ₯Έλ€.
A Conversation Among Friends
- Engine: JavaScript νλ‘κ·Έλ¨μ μμλΆν° λκΉμ§ μ»΄νμΌ λ° μ€νμ λ΄λΉνλ€.
- Compiler: Engineμ μΉκ΅¬ μ€ ν λͺ μΌλ‘ νμ± ββλ° μ½λ μμ±μ λͺ¨λ λλ¬μ΄ μμ μ μ²λ¦¬νλ€.
- Scope Manager: μμ§μ λ λ€λ₯Έ μΉκ΅¬λ‘ μ μΈ λ λͺ¨λ λ³μ/μλ³μμ μ‘°ν λͺ©λ‘μ μμ§νκ³ μ μ§ κ΄λ¦¬νλ©° νμ¬ μ€νμ€μΈ μ½λμ μ‘μΈμ€ ν μμλ λ°©λ²μ λν μΌλ ¨μ κ·μΉμ μ μ©νλ€.
μμμ λ³Έ λ€μ μ½λ
var students = [
{ id: 14, name: "Kyle" },
{ id: 73, name: "Suzy" },
{ id: 112, name: "Frank" },
{ id: 6, name: "Sarah" }
];
function getStudentName(studentID) {
for (let student of students) {
if (student.id == studentID) {
return student.name;
}
}
}
var nextStudent = getStudentName(73);
console.log(nextStudent);
// Suzy
μμ 첫λ²μ§Έ λͺ λ Ήλ¬ΈλΆν° 보면, μ°λ¦¬λ νλμ μ μΈλ¬ΈμΌλ‘ 보μ§λ§ Engineμ λ κ°μ λ³κ°μ μμ μΌλ‘ μΈμνλ€. νλλ μ»΄νμΌλ¬κ° μ»΄νμΌ μ€μ μ²λ¦¬νκ³ λ€λ₯Έ νλλ μμ§μ΄ μ€ν μ€μ μ²λ¦¬νλ€.
μ»΄νμΌλ¬λ νλ‘κ·Έλ¨μμ κ°μ₯ λ¨Όμ λ μ±μ μννμ¬ ν ν°μΌλ‘ λΆν ν λ€μ νΈλ¦¬(AST)λ‘ κ΅¬λ¬Έ λΆμνλ€. μ»΄νμΌλ¬κ° μ½λλ₯Ό μμ±νλ €λ©΄ λ λ§μ κ³Όμ μ΄μλ€. λ€μμ μ»΄νμΌλ¬κ° 첫λ²μ§Έ ꡬ문μ μ²λ¦¬νλ λ¨κ³μ΄λ€.
var student
λ₯Ό λ§λλ©΄ μ»΄νμΌλ¬λ ν΄λΉ νΉμ λ²μ λ²ν·μ λν΄ studentsλΌλ λ³μκ° μ΄λ―Έ μ‘΄μ¬νλμ§ νμΈνκΈ° μν΄ λ²μ κ΄λ¦¬μμκ² μμ²νλ€. μ‘΄μ¬ νλ€λ©΄ μ»΄νμΌλ¬λ μ΄ μ μΈμ 무μνκ³ κ³μ μ§ννλ€. κ·Έλ μ§ μμΌλ©΄ μ»΄νμΌλ¬λ (μ€νμ) μ€μ½ν κ΄λ¦¬μμκ² ν΄λΉ μ€μ½ν λ²ν·μ νμμ΄λΌλ μ λ³μλ₯Ό μμ±νλλ‘ μμ²νλ μ½λλ₯Ό μμ±νλ€.- κ·Έλ° λ€μ μ»΄νμΌλ¬λ μμ§μ΄ λμ€μ μ€νν μ½λλ₯Ό μμ±νμ¬
student = []
ν λΉμ μ²λ¦¬νλ€.
μ»΄νμΌ κ³Όμ μμ __Scope Manager__μ __Compiler__λ λμμμ΄ μνΈ μμ©νλ©΄μ μ½λλ₯Ό μμ±νλ€.
Compiler : μλ
νμΈμ, Scope Manager (Global), studentsμ΄λΌλ μλ³μμ λν 곡μ μ μΈμ μ°Ύμμ΅λλ€. λ€μ΄ λ³Έ μ μ΄ μμ΅λκΉ?
(Global) Scope Manager : μλμ, λ€μ΄ λ³Έ μ μ΄ μμ΄μ λ°©κΈ λ§λ€μμ΅λλ€.
Compiler : μλ
νμΈμ, Scope Manager, getStudent-Nameμ΄λΌλ μλ³μμ λν 곡μ μ μΈμ μ°Ύμμ΅λλ€. λ€μ΄ λ³Έ μ μ΄ μμ΅λκΉ?
(Global) Scope Manager : μλμ,νμ§λ§ λ°©κΈ λ§λ€μμ΅λλ€.
Compiler : Hey, ))Scope Manager__, getStudentNameμ΄ ν¨μλ₯Ό κ°λ¦¬ ν€λ―λ‘ μ λ²μ λ²ν·μ΄ νμν©λλ€.
(Function) Scope Manager : μκ² μ΅λλ€. μ¬κΈ° λ²μ λ²ν·μ΄ μμ΅λλ€.
Compiler : μλ
νμΈμ, Scope Manager (Function), studen-tIDμ λν 곡μ λ§€κ° λ³μ μ μΈμ μ°Ύμμ΅λλ€. λ€μ΄ λ³Έ μ μ΄ μμ΅λκΉ?
...
κ·Έλ¦¬κ³ λ°νμ κ³Όμ μμλ __Scope Manager__μ __Engine__μ΄ λννλ€.
(Global) Scope Manager : λ€, μ¬κΈ° λ³μκ° μμ΅λλ€.
Engine : Scope Manager, λͺ©νλ¬Όμ μ°Ύμμ΅λλ€. students μ°Έμ‘°λ₯Ό μ°Ύμμ΅λλ€, λ€μ΄ λ³Έ μ μ΄ μμ΅λκΉ?
(Global) Scope Manager : μ, 곡μμ μΌλ‘ μ΄ λ²μμ λν΄ μ μΈλμμΌλ―λ‘ μ¬κΈ°μ μμ΅λλ€.
Engine : κ°μ¬ν©λλ€. μ λ studentsλ€μ μ΄κΈ°ννκ³ μμ΅λλ€. μ μλμ΄ μ¬μ©ν μ€λΉκ°λμμ΅λλ€.
Engine : μλ
νμΈμ, Scope Manager (Global), nextStudentμ λμ μ°Έμ‘°λ₯Ό μ°Ύμμ΅λλ€. λ€μ΄ λ³Έ μ μ΄ μμ΅λκΉ?
(Global) Scope Manager : μ,μ΄ λ²μμ λν΄ κ³΅μμ μΌλ‘ μ μΈλμμΌλ―λ‘ μ¬κΈ°μ μμ΅λλ€.
Engine : κ°μ¬ν©λλ€. nextStudentλ₯Ό undefinedλ‘ μ΄κΈ°ννκ³ μμΌλ―λ‘ μ¬μ©ν μ€λΉκ°λμμ΅λλ€.
...
λ°λΌμ, μμ½νμλ©΄ 첫 λ²μ§Έ λͺ λ Ήλ¬Έμ
- μ»΄νμΌλ¬λ λ²μ λ³μμ μ μΈμ μ€μ νλ€.
- Engineμ΄ μ€νλλ λμ λͺ λ Ήλ¬Έμ ν λΉ λΆλΆμ μ²λ¦¬νκΈ° μν΄ Engineμ Scope Managerμ λ³μλ₯Ό μ‘°ννλλ‘ μμ²νκ³ μ μλμ§ μμ μνλ‘ μ΄κΈ°ννμ¬ μ€λΉνμ¬ λ°°μ΄ κ°μ ν λΉνλ€.
Nested Scope
lexical scopeμ μ£Όμ μΈ‘λ©΄ μ€ νλλ νμ¬ λ²μμμ μλ³μ μ°Έμ‘°λ₯Ό μ°Ύμ μ μμ λλ§λ€ μ€μ²©μ λ€μ μΈλΆ λ²μλ₯Ό μ°Έμ‘°νλ€λ κ²μ΄λ€. ν΄λΉ νλ‘μΈμ€λ λ΅λ³μ μ°Ύκ±°λ λ μ΄μ λ¬Έμ ν λ²μκ° μμ λκΉμ§ λ°λ³΅λλ€.
Undefined Mess
μ μΈμ΄ μλ λ³μλ "Reference Error: " μλ¬λ₯Ό μΆλ ₯νμ§λ§, μ μΈμ΄λκ³ μ무κ²λ ν λΉμ΄ μλμ λλ "undefined" κ° μΆλ ₯λλ€. λ κ°λ
μ νΌλνμ§ λ§μ.
νμ§λ§, typeof μ°μ°μλ λ μνμ λν΄ λͺ¨λ undefinedλ₯Ό μΆλ ₯νλ€.
var studentName;
typeof studentName; // "undefined"
typeof doesntExist; // "undefined"
μ΄ λλ¬Έμ μΈμ¬νκ² μ κ²½μ μ°μ.
Global... What!?
λ³μκ° targetμ΄κ³ strict-modeκ° μ μ©λμ§ μμΌλ©΄ νΌλμ€λ½κ³ λλΌμ΄ λ κ±°μ λμμ΄ μμλ©λλ€.
μ μ λ²μμ λ²μ κ΄λ¦¬μκ° ν΄λΉ λμ ν λΉμ μννκΈ° μν΄ μ€μλ‘ μ μ λ³μλ₯Ό μμ±νλ€.
function getStudentName() {
// assignment to an undeclared variable :(
nextStudent = "Suzy";
}
getStudentName();
console.log(nextStudent);
// "Suzy" -- oops, an accidental-global variable!