본문 바로가기
Javascript

[Javascript; 자바스크립트] 자바스크립트 클로저의 모든 것: 원리, 문제점, 그리고 해결방법

by daddydontsleep 2024. 11. 1.
728x90
728x90

사진: UnsplashSamsung Memory

자바스크립트 클로저 완벽 가이드: 실무에서 만나는 문제 해결법 [예제 코드 포함]

"클로저는 자바스크립트 개발자라면 반드시 마주치게 되는 개념입니다. 면접에서도 자주 나오고, 실제 개발 과정에서도 수시로 마주치죠. 하지만 제대로 이해하지 못하면 메모리 누수나 성능 문제를 일으킬 수 있습니다. 이 글에서는 클로저의 개념부터 실무에서 마주치는 문제들과 그 해결 방법까지 상세히 다뤄보겠습니다."

📚 목차

  1. 클로저의 개념과 기본 원리
  2. 클로저의 동작 원리와 실행 컨텍스트
  3. 실무에서 자주 발생하는 클로저 문제
  4. 문제 해결 가이드
  5. 실전 활용 사례
  6. 성능 최적화 전략
  7. 자주 나오는 면접 질문

1. 클로저의 개념과 기본 원리

클로저(Closure)는 함수와 그 함수가 선언된 렉시컬 환경의 조합입니다. 쉽게 말해, 함수가 자신이 생성될 때의 환경을 기억하는 것이죠.

1.1 기본 예제로 이해하기

function createCounter() {
    let count = 0;  // 프라이빗 변수

    return function() {
        return ++count;  // 외부 스코프의 변수에 접근
    };
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

이 코드에서 반환된 함수는 자신이 생성될 때의 count 변수를 계속 기억하고 있습니다. 이것이 바로 클로저의 가장 기본적인 예시입니다.

1.2 클로저가 유용한 이유

  1. 데이터 프라이버시
    • 변수를 외부에서 직접 접근할 수 없게 캡슐화
    • 정보 은닉 구현 가능
  2. 상태 유지
    • 함수가 호출될 때마다 이전 상태 기억
    • 함수형 프로그래밍에서 중요한 역할
  3. 모듈화
    • 관련 기능을 하나의 모듈로 묶기 가능
    • 전역 네임스페이스 오염 방지

2. 클로저의 동작 원리와 실행 컨텍스트

2.1 렉시컬 스코핑

const x = 'global';

function outer() {
    const x = 'outer';

    function inner() {
        // inner 함수는 outer의 x에 접근 가능
        console.log(x); // 'outer' 출력
    }

    return inner;
}

const innerFn = outer();
innerFn(); // 'outer' 출력

2.2 실행 컨텍스트와 스코프 체인 도식화

전역 실행 컨텍스트
│
├── x: 'global'
│
└── outer 함수 실행 컨텍스트
    │
    ├── x: 'outer'
    │
    └── inner 함수 실행 컨텍스트
        └── 스코프 체인으로 outer의 x에 접근

3. 실무에서 자주 발생하는 클로저 문제

3.1 메모리 누수 문제

function createLargeData() {
    const largeData = new Array(1000000).fill('🐘');

    return function() {
        console.log(largeData.length);
    };
}

// 이 경우 largeData는 계속 메모리에 남아있음
const dataLogger = createLargeData();

3.2 이벤트 리스너 메모리 누수

function setupHandler(element) {
    const data = new Array(1000000);

    element.addEventListener('click', function() {
        // data 배열 전체가 메모리에 계속 남아있음
        console.log(data.length);
    });
}

4. 문제 해결 가이드

4.1 메모리 누수 방지하기

class ResourceManager {
    #resources = new WeakMap();

    createResource() {
        const resource = new Array(1000000);
        const wrapper = {
            use: () => {
                if (this.#resources.has(wrapper)) {
                    console.log('리소스 사용');
                }
            },
            dispose: () => {
                this.#resources.delete(wrapper);
            }
        };

        this.#resources.set(wrapper, resource);
        return wrapper;
    }
}

// 사용 예시
const manager = new ResourceManager();
const resource = manager.createResource();
resource.use();
resource.dispose(); // 메모리 해제

5. 실전 활용 사례

5.1 React 커스텀 훅에서의 클로저

function useCounter(initialValue = 0) {
    const [count, setCount] = useState(initialValue);

    // 클로저를 활용한 카운터 로직
    const increment = useCallback(() => {
        setCount(prev => prev + 1);
    }, []);

    return [count, increment];
}

// 사용 예시
function Counter() {
    const [count, increment] = useCounter(0);

    return (
        <div>
            <p>Count: {count}</p>
            <button onClick={increment}>증가</button>
        </div>
    );
}

6. 성능 최적화 전략

6.1 메모리 사용량 최적화

function createOptimizedResource() {
    let resource = new WeakRef(new Array(1000000));

    return {
        use() {
            const data = resource.deref();
            if (data) {
                console.log('리소스 사용 가능');
            } else {
                console.log('리소스 해제됨');
            }
        }
    };
}

7. 자주 나오는 면접 질문

  1. 클로저란 무엇인가요?
    • 함수와 그 함수가 선언된 렉시컬 환경의 조합
    • 외부 변수를 기억하고 접근할 수 있는 함수
  2. 클로저의 장단점은 무엇인가요?
    • 장점:
      • 데이터 프라이버시
      • 상태 유지
      • 모듈화 가능
    • 단점:
      • 메모리 누수 가능성
      • 성능 영향
  3. 클로저를 사용하는 실제 사례는?
    • React의 훅
    • 이벤트 핸들러
    • 데이터 캐싱

마무리

클로저는 자바스크립트의 강력한 기능이지만, 제대로 이해하고 사용하지 않으면 성능 문제를 일으킬 수 있습니다. 이 글에서 다룬 개념과 해결 방법들을 실무에 적용하면서, 더 나은 코드를 작성하시기 바랍니다.

다음 시리즈 예고

  • 자바스크립트 프로토타입 깊이 파헤치기
  • 이벤트 루프와 비동기 처리의 모든 것
  • this 바인딩 마스터하기

관련 자료

  • 클로저 예제 GitHub 저장소
  • 클로저 관련 코딩테스트 문제 모음
  • MDN 클로저 문서

여러분은 실무에서 클로저와 관련하여 어떤 경험을 하셨나요?
댓글로 여러분의 경험과 해결 방법을 공유해주세요! 💬

다음 포스팅에서 다룰 주제를 투표해주세요:

  1. 프로토타입 체인 깊이 파헤치기
  2. 이벤트 루프 동작 원리
  3. 모듈 시스템 비교 분석

#JavaScript #클로저 #프론트엔드개발 #웹개발 #코딩테스트 #기술면접 #React

728x90
300x250