클로저

5o_hyun·2022년 1월 19일
1
post-thumbnail

클로저를 모르고 있다고 생각했는데, 이미 클로저를 은연중에 사용하고 있었다는 사실에 신기하게 느껴졌다!

클로저란?

클로저 ( closure ) 는 함수와 그 함수가 선언된 렉시컬 환경과의 조합이다.

내부함수가 정의될 떄 외부함수의 환경을 기억하고있는 내부함수를 말한다. 즉, 자신이 생성될 때의 환경을 기억하는 함수
함수 정의가 평가되는시점 ( 실행 x ) 에 함수가 상위스코프의 렉시컬환경을 참조를 하게 되는 것이다.

클로저를 정확하게 이해하기 위해서는 함수의 실행컨텍스트를 확실히 이해해야한다.

클로저 예제

const makeCounter = () => {
  let count = 0; // 독립변수, 자유변수

  return () => {
    return count += 1;
  }
}

const counter = makeCounter();

console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3

익명함수가 선언될 때 익명함수의 내부슬롯에 makeCounter의 렉시컬환경을 참조한다.

  1. const counter = makeCounter(); 에서 makeCounter 함수가 호출될 떄 makeCounter 함수의 컨텍스트가 생성된다.

  2. makeCounter함수의 컨텍스트안에 변수 count가 기록되고 익명함수 () => {} 가 기록, 정의된다.

  3. (익명)함수가 정의될 때 (익명)함수는 자신의 내부슬롯 [[Environment]] 에 상위스코프의 렉시컬환경이 담긴다.

  4. (익명)함수가 정의된 상위스코프 makeCounter()의 렉시컬환경을 (익명)함수의 내부슬롯에 담아놨기때문에, 계속 참조를 안끊기고 하므로 가비지컬렉션의 대상이 되지않아 참조가 계속 살아있다.

이렇게 함수객체는 정의되었을 때 자신의 내부슬롯에 그 상위 스코프의 렉시컬환경참조가 담기는것이다.

여기서 let count = 0; 은 독립변수 또는 자유변수 라고하는데,
이것이 바로 클로저를 쓰는 이유가 된다.
변수를 외부에서 접근할수없게 하기위해서, 변수를 은닉하고, 독립적으로 쓰고싶을 때 클로저패턴을 쓴다. ( 모듈화를 위함이라고도 한다. )

클로저를 사용하는 이유

1. 전역변수 사용억제

전역변수가 많으면 어디에서든 접근이 가능하므로 최대한 전역변수를 줄여서 코딩을 해야한다.

하지만 프로그램을 구현하다보면 이 함수 하나에서만 사용하는데 전역변수가 필요한 순간이 오는데, 이 때 클로저를 사용하면 된다.

2. 현재상태를 기억하고 변경된 최신상태를 유지

상태 변경이나 가변 데이터를 피하고 오류를 피하는 안정성을 증가 시킬수 있다.

3. 변수를 외부에서 접근할 수 없게 하기 위해서 = 정보은닉

클로저 단점

스코프가 종료 된 후에도 스코프 밖에서 언제든지 호출 될 수 있도록 메모리에 계속해서 저장하고 있기 때문에 메모리 사용량이 늘어난다.

클로저 해제는 null 을 대입한다고 한다.

profile
학생 점심 좀 차려

0개의 댓글