본문 바로가기
IT/JavaScript & TypeScript

[JavaScript] 클로저

by 저당단 2025. 10. 14.

3장 내용.

 

클로저를 통한 정보 은닉

function createCounter() {
    let count = 0;
    
    return function counter() {
        return ++count;
    }
}

const counter1 = createCounter();
const counter2 = createCounter();
console.log(counter1());    // 1
console.log(counter2());    // 1

count라는 변수에는 오로지 counter 함수에서만 접근이 가능하므로, 정보 은닉의 기능을 한다.

 

 

커링

여러 개의 파라미터를 받는 함수를 하나의 파라미터만 받는 함수로 연속적으로 변환하는 함수형 프로그래밍 기법. 클로저를 통한 부분 적용 함수를 이용하여 구현한다.

function curry (func) {
    return function (a) {
        return function (b) {
            return func(a, b);
        }
    }
}

function add(a, b) {
    return a + b;
}

function multiply(a, b) {
    return a * b;
}

const adder = curry(add);
const multiplier = curry(multiply);

const add7 = adder(7);
const multiply3 = multiplier(3);

console.log(add7(3), multiply3(2));    // 21 6

잘 쓰이진 않는다. 개념만 알아두기.

 

 

IIFE(즉시 실행 함수 표현식)

(function() {
    var a = "doringri";
    console.log(a);
})();

값처럼 평가될 수 있는 함수를 함수 표현식이라고 한다. 보통 변수에 대입되거나 괄호로 감싸져 있는데 이 경우는 후자이다.

선언문처럼 함수에 이름을 붙일 수도 있지만 어차피 괄호 밖에선 호출하지 못하고 애초에 바로 실행할 용도로 만든거라 굳이 붙이지 않는다.

 

함수 표현식이 즉시 실행되면서 함수 스코프를 생성하여 변수나 함수 선언의 범위를 제한할 때 사용함.

var는 블록 스코프를 지원하지 않고 함수 스코프만 지원하기 때문에 저런 게 필요했음.

 

 

비동기 코드에서의 클로저 문제

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 0);
}
// 출력: 3, 3, 3

var가 함수 스코프만 지원하기 때문에 생기는 문제로, 클로저가 외부 변수'값'이 아닌 '참조'를 기억하고 있다는 것을 나타낸다.

var로 정의한 i는 for문이 모두 돌아가면 3이라는 값이 되고, 이 값은 for문 블록 스코프 안에서만 쓰이지 않고 전역적으로 쓰인다.

그래서 console.log(i)라는 클로저는 3만 세 번 출력한다.

 

let value = 1;
setTimeout(() => console.log(value), 100);
value = 2;
// 출력: 2

이것도 위와 같이 클로저가 '참조'를 기억하고 있기 때문에 나타나는 현상이다.

 

 

클로저메모리 누수 문제

- 참조를 유지하는 외부 변수가 남아 있으면 누수 발생 가능. 더 이상 사용되지 않으면 명시적으로 null로 설정해야 함.

- addEventListener는 once 옵션을 통해 리스너가 한 번만 실행되게 할 수 있음.

 

 


1장도 정리할걸 하며 후회중 ...