• 모닥위키모닥위키
  • 모닥위키
위키
  • 임의문서
  • 주간인기
  • 문서
  • 시리즈
    AAAdddvvveeerrrtttiiissseeemmmeeennntttAdvertisement

    © 2025 modak.wiki All rights reserved.

      클로저

      Chapter 21 - Closures

      컴퓨터/IT학습
      lu

      luasenvy (luasenvy)

      CC BY 4.0 국제규약

      클로저

      function makeClosure() { // 외부함수
        const name = "luasenvy"; // 외부함수 멤버
      
        return function someFn() { // 내부함수
          return name; // 외부함수 멤버 참조
        }
      }
      
      const fn = makeClosure();
      fn(); // "luasenvy"
      

      클로저는 선언적인(문법적, 어휘적) 실행환경을 일컫는다. 말이 좀 어려운데 위 예시를 보면 makeClosure() 함수는 someFn() 함수를 반환한다. someFn() 함수는 makeClosure() 함수의 내부에서 선언된 함수로 외부함수에서 선언된 name을 접근할 수 있고 이 값을 반환하고 있다. 이 연결을 이어보면 makeClosure -> someFn -> makeClosure.name 식으로 참조하고 있다.

      1. makeClosure() 실행
      2. someFn() 함수 반환 -> fn 변수에 할당
      3. fn() 실행

      외부함수 멤버 name은 외부함수가 실행중일 때만 유효하다. makeClosure() 밖에는 존재하지 않는 변수임은 너무나도 당연해보인다. 또한, someFn()을 실행할 때에도 그 어디에도 name 변수를 초기화 하는 코드는 없다. 직관적으로 보았을 때 someFn()을 실행하고 name을 참조하는 순간에 Uncaught ReferenceError: name is not defined 오류가 발생할 것으로 예상할 수 있다.

      그러나 자바스크립트는 someFn이 반환될 때 선언된(어휘적) 위치에 맞는 환경(컨텍스트)인 클로저를 구성하여 이 참조들이 올바르게 작동할 수 있도록 유지시킨다. 이러한 작동은 여러가지를 가능하게 해주지만 유지보수가 복잡해지고 예상하지 못했던 동작을 만날 수도 있다.

      응용1. 함수 팩토리

      const makeFn = (width) => {
        return (el) => {
          el.style.width = width
        };
      }
      
      const changeWidth100 = makeFn(100);
      const changeWidth200 = makeFn(200);
      
      div1.addEventListener(e => changeWidth100(e.target));
      div2.addEventListener(e => changeWidth200(e.target));
      

      이 클로저를 활용하면 함수 팩토리처럼 사용할 수 있다.

      응용2. 비공개 멤버 구현

      const human = (() => {
        let age = 0;
        const moreThanFive = () => age > 5;
        
        return {
          isOverFive() {
            return moreThanFive();
          },
          setAge(_age) {
            age = _age;
          },
          getAge() {
            return age;
          },
        };
      })();
      
      console.info(human.getAge());
      

      과거 자바스크립트에서는 private 멤버를 만들 수 있는 문법이 제공되지 않았기 때문에 위처럼 클로저를 응용하여 비공개 멤버를 흉내내기도 한다. moreThanFive(), age 멤버는 클로저가 생성되면서 참조를 잃지 않고 유지되지만 외부에서 접근하려면 isOverFive(), getAge(), setAge()와 같은 명시적으로 공개한 메서드를 사용해야만 접근이 가능하다.

      초판: 2024. 08. 19. 22:55:43

      © 2024 이 문서는 "CC BY 4.0 국제규약" 라이선스로 배포 되었습니다. 모든 권리는 저자에게 있습니다.

      클로저

      클로저
      응용1. 함수 팩토리
      응용2. 비공개 멤버 구현