[JS] 클로저(Closure) 쉽게 이해하기

유니·2022년 5월 26일
3

JavaScript

목록 보기
2/9

클로저(Closure)

함수 + 함수를 둘러싼 렉시컬 환경(Lexical environnment)

클로저를 처음 공부할 때는 저 말이 이해가 안되어서(일단 렉시컬 환경이 뭔지도 몰랐다) 다양한 사이트와 동영상을 뒤지며 다른 여러 버전의 정의를 찾아봤다.

  • 자신이 생성(선언)된 시점의 환경을 기억하는 함수
  • 함수 호출이 종료되었어도 함수의 변수 or 인자에 접근 할 수 있는 함수
  • Closure make it possible for a function to have "private" variables. (클로저는 함수가 private한 변수를 가질 수 있게 한다.)

왜 클로저(closure : 폐쇄) 인가?

외부 함수 호출이 종료된 후에도 함수의 내부변수에 대한 메모리할당을 유지하지만 직접 볼 수 없게 은닉화 하기 때문이다

  • 클로저 기법을 사용하는 이유는 전역변수를 사용하지 않으려는 목적인듯하다.
    개나소나 접근해서 들여다보고 변경까지 할 수 있는 전역변수를 사용하는 것은 매우위험하기 때문이다.
    하지만 클로저를 사용하면 전역변수를 사용하지 않으면서도 클로저 함수 내부의 변수에 계속 접근 할 수 있기때문에 이 문제가 깔끔하게 해결된다.

이런걸 왜 알아야 할까?

  • 자바스크립트 엔진의 동작원리를 정확하게 알아야 적절한 설계와 개발을 해낼 수 있다.
  • 자바스크립트 특성을 적절하게 응용하여 고급진 코드를 짤 수 있다.
  • 나중에 내가 라이브러리를 만들 때/남이 만든 라이브러리 내부코드를 뜯어보며 이해할 때 매우 도움이 될것이다.

내가 겪었던 클로저

  • 며칠전에 전임자가 짜놓은 코드중에 resize 이벤트에 달아 놓은 콜백함수가 디바운스를 엉뚱하게 사용하고 있는것을 발견했다.

    • 잘못된 디바운스
    const debounce = (event) => {
        let timer;
        if (tiemr) clearTimeout(timer);
        timer = setTimeout(callback, delay, event);
        };
    };
    useEffect(() => {
        window.addEventListener('resize', debounce)
        return () => {
          window.removeEventListener('resize', debounce)
        }
    },[])

    -> 이렇게 쓰면 resize 될 때마다 timer 변수롤 계속 새로 만들어버린다

    • 옳게된 디바운스(by 클로저)
    const debounce = () => {
        let timer;
        return event => {
          if (tiemr) clearTimeout(timer);
          timer = setTimeout(callback, delay, event);
        }
    };
    useEffect(() => {
      window.addEventListener('resize', debounce())
      return () => {
        window.removeEventListener('resize', debounce())
      }
    },[])

    -> 이렇게 쓰면 timer는 한번만 생성되고 debounce() 가 리턴하는 콜백함수는 은닉화된 timer를 참조할 수 있게 된다!

profile
추진력을 얻는 중

1개의 댓글

comment-user-thumbnail
2022년 8월 27일

감사합니다

답글 달기