공부 정리/You Don't Know Js

[YDKJ] Scope & Closures - The Scope Chain

경적필패. 2023. 5. 9. 00:10
반응형

요약

Chapter 3: The Scope Chain

  • 중첩된 스코프에서 연결된 스코프들을 스코프 체인이라고함.
  • 체인은 방향성을 가지며 상위/외부 방향으로 탐색을 함.

 
 

"Lookup" Is (Mostly) Conceptual

  • 일반적으로 변수가 어떤 스코프에서 비롯되었는지는 초기 컴파일링 과정에서 결정됨.
  • 런타임동안에 스코프가 변경되진 않음 => 그러나 런타임때 결정 될 수는 있음.(현재 프로그램에는 선언 안되어 있는데 다른 프로그램 전역 스코프에 있을 때)
  • 챕터2에서는 엔진이  계속해서 스코프체인을 탐색하는 것처럼 말했지만, 사실 이미 정보가 알려져있어서 탐색안함.

 

Shadowing

쉐도잉 => 가리는 것을 의미.

var studentName = "Suzy";

function printStudent(studentName) {
    studentName = studentName.toUpperCase();
    console.log(studentName);
}

printStudent("Frank");
// FRANK

printStudent(studentName);
// SUZY

console.log(studentName);
// Suzy

이러한 코드가 있을 때, printStudent의 studnetName은 매개변수 studentName을 가린다.
즉 printStudent 함수 안에서는 전역 studentName에 접근할 수 없음!
이게 쉐도잉
 

Global Unshadowing Trick

이 기법은 사용하지 않는게 좋으나, 기존 프로그램에 있을 수 있어 알아둬야함!

var studentName = "Suzy";

function printStudent(studentName) {
    console.log(studentName);
    console.log(window.studentName);
}

printStudent("Frank");
// "Frank"
// "Suzy"

위 코드 처럼

쉐도잉 땜에 studentName에 접근할 수 없지만, window객체를 이용하면 전역 studentName에 접근할 수 있다.

 

var one = 1;
let notOne = 2;
const notTwo = 3;
class notThree {}

console.log(window.one);       // 1
console.log(window.notOne);    // undefined
console.log(window.notTwo);    // undefined
console.log(window.notThree);  // undefined

그러나 let, const, class의 경우에는 사용할 수 없음.

 

Illegal Shadowing

let은 var을 가릴 수 있지만, var은 let을 가릴 수 없음!!

function something() {
    var special = "JavaScript";

    {
        let special = 42;   // totally fine shadowing

        // ..
    }
}

function another() {
    // ..

    {
        let special = "JavaScript";

        {
            var special = "JavaScript";
            // ^^^ Syntax Error

            // ..
        }
    }
}

let은 중복선언을 허용하지 않음!!

 

그러나

let s = "sout";
const a = () => {
  var s = "sin";
  console.log(s);
}
a(); //sin
console.log(s); //sout

위 코드 처럼 함수의 경계 안에 있으면 외부 스코프의 let을 가릴 수 있음

Function Name Scope

함수선언과 함수 표현식의 차이가 있음.

function askQuestion() {
    // ..
}

이 코드는 함수 선언으로, 전역스코프에 형성됨.

 

var askQuestion = function(){
    // ..
};

이 코드는 표현식으로, 호이스팅 되지 않음.

 

var askQuestion = function ofTheTeacher() {
    console.log(ofTheTeacher);
};

askQuestion();
// function ofTheTeacher()...

console.log(ofTheTeacher);
// ReferenceError: ofTheTeacher is not defined

두 방식을 모두 사용한 이 코드도 표현식처럼 동작함.

 

 

a();
const a = function () { console.log("haha") };

 

그러나 익명 표현식은 정상적으로 위의 코드가 동작함.

Arrow Functions

  • 화살표 함수는 렉시컬로 익명임.
  • 짧은 구문으로 작성 가능 => 저자 생각은 아님.
  • 화살표 함수도 독립적인 스코프 버킷을 만들고, 함수 스코프와 같은 방식으로 동작함.
     

 

느낀 점

함수와 스코프를 중점으로 다룬 챕터였다.

평소 let과 var을 혼용해서 쓰지 않기 때문에 생각해보지 않은 관점을 볼 수 있었다.

나도 평소에 arrow function을 짧은 구문의 장점 때문에 자주 이용하고 좋다고 생각했는데 저자는 그렇게 생각하지 않는 것 같다... 책을 좀 더 읽어 봐야겠다.

반응형