ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Notes from reading 🔖 You Don't Know JS Yet - 11
    JavaScript 2026. 5. 9. 22:10

    ### 파트2 - Chapter 6 스코프 노출 제한

     

    함수의 전용 스코프는 OK, 그렇다면 블록은 왜 스코프가 필요한가 ??

    • 정보 보호 분야에서는 최소 권한의 원칙 (POLP)가 있다. 이를 약간 변형한 최소 노출의 원칙 (POLE)이 해당 내용에 적용될 수 있다.
    • 최소 권한, 접근 최소, 노출 최소가 필요하다는 원칙이다. (방어적인 아키텍처 설계)
    • 한 구성 요소의 장애가 나머지 시스템에 미치는 영향을 최소화 -> 시스템 전체 보안의 강화
    • POLE를 따를 때 가장 최소화 하고 싶은 것은 ?? 바로 스코프마다 등록된 변수의 노출
    • 변수가 노출되면 => 이름 충돌의 위험, 예기치 않은 작동, 의도하지 않은 종속성의 문제가 발생할 수 있다.

     

    • 따라서, 가능한 한 가장 낮은 스코프에 변수/함수 선언을 숨기는 것이 중요하다.
    • 때로는 중간에 함수 스코프를 사용하면, 해당 원칙을 적절하게 실천할 수 있다.
    • 다만, 이를 실천하기 위해서 새 함수, 새 스코프를 작성하는 것은 귀찮다.
    • 변수나 함수의 이름을 숨길 땐 함수 표현식을 사용하는 것이 좋을 수도 있다.
    • 또는 익명 함수 표현식을 사용해도 좋다.
    var func = (function test() {
      var call_times = 0;
      console.log("숨김");
      call_times++;
      
      function getCallTimes() {
        return call_times;
      }
      
      return getCallTimes;
    })()
    • 위에서는 즉시 실행 함수 (IIFE)가 사용되었다.
    • IIFE는 변수나 함수를 숨기는 스코프를 만들고 싶을 때 유용하다. (이름을 익명으로 해도 괜찮음)
    • IIFE도 온전한 함수이기 때문에, 잘못 사용하면 함수 경계 변경으로 문제가 될 수 있다.
    • return, this, break, continue가 사용된 경우에는 IIFE가 좋은 선택이 아닐 가능성이 높다.

     

    • 블록은 let/const 같은 블록 스코프 선언을 포함할 필요할 때만 스코프로 작용
      (let cont 변수 선언이 있어야지 스코프가 필요해져서 블록 스코프가 생성된다는 뜻)
    • TDZ를 방지하기 위해서 스코프 최상단에 let, const를 쓰는 것이 좋다.
      즉, 최상단에 변수를 선언하지 않는 경우는 블록 스코프 구분을 고민해보야 한다. (변수 노출 범위를 줄임)
    {
      const hi = 'hi';
      
      {
        // 새로운 블록 스코프
        let newHi = hi + "_NEW";
      }
    }

     

    • var -> 전체 함수에 속한 변수. var는 사용된 위치와 관계없이 가장 가깝게 감싼 함수 스코프에 붙는다.
    • 때때로 let 대신 var를 사용해서 시각적으로 '함수 스코프 변수'라는 의미를 전달할 수 있다. 
      (반대로 let은 블록 스코프라는 의미가 전달)

     

    • 지금까지의 내용의 예외가 있다. catch문이다.
    • catch절에서 선언된 변수는 catch문 밖에서 사용 불가능하다.
    try {
       aaa();
    }  catch (err) {
       // catch 문에서 err 객체를 선언하지 않으면 catch 블록은 스코프 형성 X 그냥 블록으로 처리됨
       console.log(err);
    }
    
    console.log(err); // ReferenceError err은 선언되지 않은 변수
    • 오류 객체를 선언하지 않음으로써, 스코프를 생성하지 않고 때로는 이로써 약간의 성능 향상을 꽤할 수 있다.

     

    • 블록 안에서 직접 함수 선언 방식으로 함수를 선언하면 ??? 블록 내 함수선언 (FiB)
    • 함수를 조건부로 선언하는 경우 등에서 해당 이슈가 있을 수 있다.
    • 다만, FiB의 경우 브라우저간에도 동작 차이가 있을 수 있고, 비브라우저 환경에서도 동작이 다르다. (디버깅이 어렵다)
    • 따라서.... FiB의 경우는 절대 사용하지 않는 것이 좋다. 블록 안에서 함수를 선언하지 말자. 함수 선언은 함수의 최상위 스코프나 전역 스코프에서 하자!
    var a = true;
    
    if (a) {
        // 블록 내부에서 함수 선언 (FiB)
        function foo() {
            return "블록 내부 foo";
        }
    }
    
    // 예상: 함수가 정의되지 않음
    // 실제: 브라우저에 따라 다르게 동작하거나, 
    //      블록 외부에서도 호출될 수 있는 위험이 있음 (호이스팅)
    console.log(foo()); // "블록 내부 foo"

     

Designed by Tistory.