ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Notes from reading 🔖 You Don't Know JS Yet - 7
    JavaScript 2025. 12. 11. 16:34

    ### 파트 2 - chapter 2 렉시컬 스코프

     

    • 컴파일레이션 중 스코프가 결정되는 방식 -> 렉시컬 스코프
    • 스코프의 블록은 중첩이 가능한데, 스코프 버블은 부모 스코프 버블에 온전히 포함되기에, 한 스코프가 두 개의 스코프에 동시에 포함될 수는 없다.
    • 어느 스코프에 변수가 포함되는지 결정짓는 절차 -> 탐색 (이 작업은 런타임 X 컴퍼일 O 스코프에 대한 내용은 미리 확정된다.)
      • 변수가 사용된 스코프에서 변수가 선언되지 않은 경우, 바깥/위의 스코프를 찾게되는데 찾을 때 까지 이는 반복된다 (recursive)

     

    • JS 엔진 내부 역할
      • 엔진: 컴파일 책임지고 JS 프로그램 실행
      • 컴파일러: 파싱 & 코드 생성
      • 스코프 매니저: 선언된 모든 변수 및 식별자의 탐색 및 목록 관리. 코드 실행 시 변수 & 식별자 접근 규칙 강제화 (함수/전역 스코프 매니저 존재)
    • 컴파일 과정에서 변수/식별자에 대한 접근을 스코프 매니저에 질의하게 되고, 해당 정보가 없는 경우 스코프 매니저가 해당 정보를 생성 및 저장한다
    • 프로그램 실행 시에는 JS엔진이 스코프 매니저와 질의를 하며 변수/식별자의 정보를 제공받는다
    • 식별자 var의 경우, 선언 시 자동으로 undefined로 초기화되어 사용이 가능해진다 (선언 O 초기화 X -> TDZ 상태)

     

    • 탐색이 실패한 경우, 엄격모드 on/off에 따라서 오류가 다르게 처리됨
    • 식별자 사용 시 해당 변수를 못찾는 경우 -> RefernceError (선언되지 않은 변수의 사용)
    • undefined의 경우 변수는 발견되었는데 (선언 O) 해당 시점에 값이 없는 경우이다.
    • 선언되지 않는 변수나 값이 없는 변수나 typeof로 찍어보면, 똑같이 undefined가 반환되어 헷갈릴 수 있다.
    • undefined라는 오류를 만난 경우에 -> undefined인지, undeclared인지 혼동하지 않도록 노력해야 한다
    • 엄격모드가 아닐 때, 미선언 변수를 만나면 스코프 매니저가 자기 멋대로 전역 변수를 만드는 경우가 있다
      • 따라서, 엄격모드는 필요하다 💖 (엄격 모드 였으면, RederenceError가 발생했다)

     

    // [전역 스코프 버블]
    var globalMsg = "나는 전역 변수다 (Global)";
    
    function outerFunc() {
        // [outerFunc 스코프 버블]
        // 부모: 전역 스코프
        var outerMsg = "나는 외부 함수 변수다 (Outer)";
    
        function innerFunc() {
            // [innerFunc 스코프 버블]
            // 부모: outerFunc 스코프
            var innerMsg = "나는 내부 함수 변수다 (Inner)";
    
            console.log(innerMsg);  // 1. 현재 스코프에서 찾음 -> 성공!
            console.log(outerMsg);  // 2. 현재 스코프에 없음 -> 위(outerFunc)로 가서 찾음 -> 성공!
            console.log(globalMsg); // 3. 현재X -> 위X -> 더 위(전역)로 가서 찾음 -> 성공!
            
            // console.log(nothing); // 4. 전역까지 갔는데 없음 -> ReferenceError 발생!
        }
    
        innerFunc();
    }
    
    outerFunc();
    // ⚠️ 엄격 모드가 아닐 때 (비추천)
    function looseMode() {
        // 선언 키워드(var, let, const) 없이 변수에 값을 넣음
        msg = "하하! 나는 의도치 않게 전역 변수가 되었다!"; 
        // 설명: 스코프 매니저가 "어? 없네? 에이 그냥 전역에 만들어 줄게" 하고 맘대로 생성함.
    }
    
    looseMode();
    console.log(msg); // 출력됨 (끔찍한 상황)
    
    
    // 🛡️ 엄격 모드 사용 (추천)
    function strictMode() {
        "use strict"; // 엄격 모드 발동!
        
        // errorMsg = "나는 생길 수 없다..."; 
        // 설명: 스코프 매니저가 "건방지게 선언도 없이? 안 돼!" 하고 ReferenceError를 던짐.
    }
    
    strictMode(); // ReferenceError: errorMsg is not defined 발생
    // 1. 선언은 했으나 초기화하지 않음 (Undefined)
    var student; 
    
    console.log(student); // undefined (값 자체가 '없음'으로 정의됨)
    console.log(typeof student); // "undefined"
    
    
    // 2. 선언조차 하지 않음 (Undeclared)
    // console.log(ghost); // ReferenceError! (프로그램 멈춤)
    
    
    // 3. typeof의 안전함 (안전 가드)
    // ghost라는 변수가 선언되었는지 모를 때, 그냥 쓰면 에러가 나지만 typeof는 에러를 안 냄.
    if (typeof ghost === "undefined") {
        console.log("ghost 변수는 선언되지 않았거나, 값이 없습니다. (안전하게 처리됨)");
    }
Designed by Tistory.