[JavaScript] 클로저 이해하기

서동경·2023년 2월 19일
1
post-thumbnail

🍀 클로저(Closure)란?

클로저란 함수 자신이 선언될 때의 환경을 기억한 상태로 호출될 때의 환경에 접근할 수 있는 것을 말한다.

여기서 말하는 선언될 때의 환경이란, 실행 컨텍스트의 개념인 렉시컬 환경(Lexical Environment)이다. 렉시컬 환경의 '해당 스코프의 변수와 함수의 식별자를 기억하는 역할'이 클로저와 연관되어 있다.

즉 클로저 함수는 자신이 선언될 때의 렉시컬 환경을 기억한 상태로, 호출 될 때의 환경에 접근할 수 있는 함수이다. 자신이 선언될 때의 렉시컬 환경에 의해 내부 함수의 변수에 접근할 수 있는 것이고, 호출될 때의 환경에 의해 외부 함수의 변수에도 접근할 수 있는 것이다.

동시에 클로저 함수는 외부에서 클로저 내부의 변수에 접근할 수 없는 캡슐화 기능을 가지게 된다. 그래서 "폐쇠"라는 뜻을 가진 클로저라는 이름으로 불리는 것이다.

스코프를 공부할 때, "스코프는 중첩이 가능하고 안쪽 스코프에서 바깥쪽 스코프로는 접근할 수 있지만 반대로는 불가능하다."라는 내용을 배웠다. 이 내용이 클로저에 대한 설명이다. 즉 클로저는 스코프와 밀접한 연관이 있는 개념이다.

🔎 클로저 예시와 활용

💬 외부 변수에 접근하는 클로저 함수

function outer() {
  let count = 0;

  function inner() {
    count++;
    console.log(count);
  }

  return inner;
}

const counter = outer();
counter(); // 1
counter(); // 2
counter(); // 3

inner() 함수는 클로저 함수로써 외부 변수인 count 변수에 접근하고 있다. 즉 inner() 함수가 선언된 때의 렉시컬 환경인 outer 함수의 변수들까지 참조할 수 있는 것이다.

이러한 클로저의 특징은 특정 변수의 상태를 유지할 때 유용하게 쓰일 수 있다. 이러한 상태 유지 기능은 클로저가 가장 유용하게 사용되는 상황이다.

function storeCount() {
  let count = 0; // 카운트 상태 유지

  return function() {
    count++; // 카운트 증가
    return count; // 현재 카운트 값 반환
  }
}

const counter1 = storeCount();
console.log(counter1()); // 1
console.log(counter1()); // 2
console.log(counter1()); // 3

const counter2 = storeCount();
console.log(counter2()); // 1
console.log(counter2()); // 2
console.log(counter2()); // 3

이런식으로 storeCount() 함수를 통해 count 변수의 상태를 유지하여 counter1, counter2 변수에 각각 할당해줌으로써 해당 변수들을 독립적으로 관리할 수 있다.

💬 은닉화(모듈화)

function getPassword() {
  const password = "mySuperSecretPassword123";

  function getPasswordClosure() {
    return password;
  }

  return getPasswordClosure;
}

console.log(getPassword()); // [Function: getPasswordClosure]

const getPasswordFunction = getPassword();
console.log(getPasswordFunction()); // "mySuperSecretPassword123"

getPassword() 함수는 password 변수를 가지고 있고 해당 변수를 참조하고 있는 메서드를 가진 객체를 반환한다. getPassword() 함수는 password 변수에 대해 클로저를 형성하고 있기 때문에 외부에서 직접 접근할 수는 없고 오직 getPasswordClosure() 메서드를 통해 접근할 수 있다. 클로저는 이처럼 정보를 은닉하고자 할 때에도 유용하게 사용된다.

profile
개발 공부💪🏼

0개의 댓글