본문 바로가기
안녕하세요 :) FE 개발자 윤지홍입니다.
저는 리액트를 주로 사용해요.
UX/UI디자인에도 관심이 있어요.
Javascript React NextJs NodeJs Flutter HTML CSS PHP
👋
클로저(Closure)와 렉시컬 스코프(Lexical Scope)
jiiii-hong | Javascript | 2022년 08월 16일

클로저(Closure)와 렉시컬 스코프(Lexical Scope)

클로저(Closure)와 렉시컬 스코프(Lexical Scope)

jiiii-hong Javascript 2022년 08월 16일

렉시컬 스코프(Lexical Scope) 란?

렉시컬 스코프를 번역하면 "어휘 범위"라고 하지만 보통 "정적 범위", "정적 스코프"라고 한다.
렉시컬 스코프는 함수가 어디서 실행되는지가 아닌 어디서 선언되었는지에 따라 상위 스코프를 결정한다.

클로저(Closure) 란?

클로저란 함수가 속해있는 렉시컬 스코프를 기억하여 함수가 렉시컬 스코프 밖에서 실행될 때에도 해당 스코프에 접근할 수 있게 하는 기능을 말한다.


쉽게 말해 외부 함수의 실행 컨텍스트가 종료된 이후에도 내부 함수에서 외부 함수의 컨텍스트에 접근할 수 있게 해주는 기능을 말한다.


아래 코드를 통해 살펴보자

const test = () => {
  const a = 123;

  const res = () => {
    console.log(a)
  }

  return res
}

const app = test();
app() // result: 123

실행 컨텍스트에서 test 함수는 실행을 마치고 사라진다. 부모 함수의 컨텍스트 정보가 모두 사라졌는데 콘솔을 확인해보면 123이 찍혀있다.
즉 자식 함수가 남아있다면 이미 실행이 종료된 부모 함수의 컨텍스트 정보(선언된 변수나 함수 등의 정보)에 접근할 수 있다.

클로저에 대한 착각

주변 개발자들에게 물어보니 클로저가 그저 함수안에서 함수를 사용하거나 단지 함수를 리턴하는 것이 클로저라고 오해하는 분들이 많았다.
클로저는 내부 함수에서 외부 함수의 지역 변수를 사용 했을때만 아래처럼 클로저로 묶인다.

const a = () => {
    const name = "이름";

    return () => {
      console.log(name);
    };
  };

  const b = a();

  console.log([b]);

내부 함수에서 외부함수의 지역변수를 사용했을 때


내부 함수에서 외부 함수의 지역변수를 사용하지 않았을 때

클로저가 필요한 이유

클로저가 필요한 첫 번째 이유에는 전역 변수 사용을 최소화할 수 있다는 점이다. 전역 변수는 언제 어디서든 접근 가능하기 때문에 예기치 못한 상황(버그) 코드 추적이 힘들어질 수 있기 때문에 최대한 전역 변수 사용을 줄이는 게 좋다.


두 번째는 클로저를 활용하면 외부 함수의 컨텍스트에는 내부 함수 외에는 접근이 불가능하기 때문에 변수 값을 은닉하는데 유리하다.


세 번째는 코드 재사용에 유리하다. 아래 코드를 보면 aCounter와 b카운터는 같은 함수를 사용했지만 각각 독립적인 값을 갖게된다.

const counter = () => {
  let num = 0;

  return () => {
    num++;

    return num;
  };
};

const aCounter = counter();
const bCounter = counter();