모던 자바스크립트 Deep Dive - 24장 클로저

어제보다·2024년 10월 11일
post-thumbnail

클로저 (Closure)

1️⃣ 클로저란❓

  • MDN에서는 클로저를 "클로저는 주변 상태(어휘적 환경)에 대한 참조와 함께 묶인(포함된) 함수의 조합입니다. 즉, 클로저는 내부 함수에서 외부 함수의 범위에 대한 접근을 제공합니다." 라고 정의하고 있다.

❗️ 클로저를 이해하기 위해서는 먼저 렉시컬 스코프에 대한 이해가 필요하다.

why? 클로저가 렉시컬 스코프에 기반하여 동작하기 때문이다.

렉시컬 스코프란 코드가 작성된 시점에서의 변수의 유효 범위를 의미한다. 즉, 함수가 어디서 정의되었는지에 따라 그 함수가 접근 할 수 있는 변수의 범위가 결정된다.
다른 말로 정적 스코프라고도 한다.

다음 예시 코드를 살펴보자.

function outer() {
    let outerVar = 'messi';
       function inner() {
        console.log(outerVar);
    }
    inner();
}
outer(); // 'messi' 출력

위 코드에서 inner 함수는 outer 함수 내에서 정의되었기 때문에 outerVar 변수에 접근할 수 있다. 이것이 렉시컬 스코프의 기본 개념이다.

이번엔 다른 예시 코드를 확인해보자

const x = 1; // 전역 변수 x를 1로 선언
function foo() {
  const x = 10; // foo 함수 내에서 지역 변수 x를 10으로 선언
  bar(); // bar 함수를 호출
}
function bar() {
  console.log(x); // 전역 변수 x를 참조하여 출력
}
foo(); // 1
bar(); // 1

둘 다 1을 출력하게 된다. 이유는 js는 함수의 호출 위치에 영향을 받는 동적 스코프가 아니라 선언이 어디서 되었는지에 따라 결정되는 정적스코프(렉시컬 스코프)이기 때문이다.

2️⃣ 클로저를 사용하는 이유

  • 이제 클로저를 사용하는 이유에 대해 알아보자.

우선 다음 코드를 살펴보자.

let cnt = 0;
function cntPlus(){
  cnt = cnt + 1;
}
console.log(cnt); // 0
cntPlus();
console.log(cnt); // 1

cnt = 100;
cntPlus();
console.log(cnt); // 101

위 코드에서는 여러가지 문제점이 있다.

  • 전역 변수 사용: cnt가 전역 변수로 선언되어 있어, 코드의 다른 부분에서도 접근 및 수정이 가능합니다. 이는 의도치 않은 변수 변경으로 인해 버그를 유발할 수 있다.
  • 데이터 은닉 부재: cnt가 외부에서 자유롭게 수정될 수 있어, 카운터의 무결성이 보장되지 않는다.
  • 재사용성 낮음: 같은 패턴의 카운터를 여러 개 생성하고 싶을 때, 전역 변수와 함수를 반복적으로 정의해야 한다.

다음은 클로저를 활용한 코드입니다.

const createCounter = () => {
  let cnt = 0; // 카운터 변수는 외부에서 접근 불가

  const increment = () => {
    cnt += 1;
    console.log(cnt);
  };

  const reset = () => {
    cnt = 0;
    console.log('카운터가 초기화되었습니다.');
  };

  const getCount = () => cnt;

  return { increment, reset, getCount };
};

const counter = createCounter();
console.log(counter.getCount()); // 0
counter.increment(); // 1
counter.increment(); // 2
console.log(counter.getCount()); // 2

counter.reset(); // '카운터가 초기화되었습니다.'
console.log(counter.getCount()); // 0
  • 이제는 외부에서 cnt라는 변수에 접근할 수가 없게 되었습니다.

  • 클로저를 통해 cnt 변수를 외부에서 직접 접근할 수 없도록 함으로써, 데이터를 은닉하고 이를 통해 값이 외부 코드에 의해 임의로 변경되지 않도록 보호할 수 있습니다.

출처:
https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures
https://www.youtube.com/watch?v=LL0DGc5pg7A

profile
똑똑해지는중...

0개의 댓글