자바스크립트 클로저

Junbro·2022년 2월 20일
1

JavaScript

목록 보기
1/2

오늘은 자바스크립트 '클로저 (Closure)' 개념에 대해 조사하고 정리하는 시간을 가져보자.

렉시컬 스코프 (Lexical scoping)

먼저, 클로저의 개념을 알기전에 렉시컬 스코프 관한 이해가 필요하다.

'자바스크립트는 언어 특성상 함수가 정의되는 시점에 상위 스코프가 결정된다.'
이 말의 의미를 예시를 통해 살펴보자

function init() {
    var name = "Mozilla"; 
    function displayName() { 
        alert (name); 
    }
    displayName();    
}
init();

init이라는 외부함수가 존재함고 그 내부에 displayName의 이름을 가지는 내부함수를 '정의'하고 있다.
displayName 함수가 init이라는 함수 내부에서 정의되고 있으므로, init 함수를 상위스코프로 가진다.

이 부분에서 중요한 점은 실행되는 시점이 중요한게 아니라 함수가 정의되는 시점을 봐야하는 것이다.

조사하면서 이해에 도움이 되는 설명이 있었는데 '자식 함수는 부모 함수를 어휘적으로 묶는 함수라고 부릅니다.'
이 설명대로 displayName 자식함수가 init이라는 부모함수를 묶었고, 부모함수에 정의된 name이라는 변수에 접근할 수 있었던 것이다!

이 렉시컬 스코프가 컴파일 시점에 결정되므로 정적스코프라고 불린다.


위 사진에서 보는 것과 같이 최하단의 내부함수는 상위스코프 나아가 전역 스코프 변수들에 접근할 수 있지만, 반대의 경우 외부에서는 내부의 변수들로 접근할 수 없다.

클로저

클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다 - MDN

MDN에서 위 설명을 들었을 때 도저히 클로저가 뜻하는게 먼지 이해가 되지 않았다.

그럼 위 말을 이해하기 위해 예시를 통해 살펴보자

function makeFunc() {
  var name = "Mozilla";
  function displayName() {
    alert(name);
  }
  return displayName;
}

var myFunc = makeFunc();
myFunc();

makeFunc라는 외부함수를 만들고 그 내부에 displayName 내부함수를 선언하였다.

makeFunc()를 실행하면서 내부함수를 리턴해주면서 외부함수는 실행이 완료되었다. (함수의 생명주기가 끝났다.)
그렇다면 외부함수에 정의된 'name' 변수 생명이 다하여 사용할 수 없을 것이라고 생각하지만 우리가 배우고 있는 이 '클로저 (myFunc)' 아이 덕분에 외부함수를
통해 리턴받은 내부함수 (displayName)을 실행했을 때 'Mozilla'가 출력되는 것을 확인할 수 있다.

클로저를 통해 렉시컬 스코프를 통해 정의된 상위 스코프를 기억 (참조)하고 있다!

비유를 하자면 클로저를 통해 패키지를 형성(1 + 1, 동봉) 했다! 라고 볼 수 있을 거 같다.

클로저를 통해 얻는 이점

클로저를 통해 변수를 은닉화 (hiding) 시킬 수 있다.

위 말을 이해하기 위해 아래 예시를 살펴보자

function makeCounter() {
  let num = 0;

  return function () {
    return num++;
  };
}

let counter = makeCounter();

console.log(counter());
console.log(counter());
console.log(counter());
0
1
2

makeCounter 외부함수에서 num을 선언하고 0으로 초기화한다. 그리고 num을 리턴 후 값을 1씩 증가씨키는 내부함수를 리턴한다.

우리가 배운 클로저 개념을 도입해보면 외부함수가 리턴하는 익명함수가 클로저가되서 상위 스코프에 정의된 'num' 변수와 함께 패키지로 'counter' 변수에 담길 것이다.
counter 함수를 호출하면서 num 변수가 증가하는 것을 볼 수 있다. 이제 num 변수는 오직 counter (클로저) 함수를 통해서만 값을 조작할 수 있다. 우리가 임의로 num 변수에 값을 할당하거나, 변경할 수 없게되었다.

이렇게 클로저를 통해 은닉화에 이점을 가져갈 수 있다!

참고한 자료들 출처

MDN
Lexical scope in JavaScript
자바스크립트 중급 강좌 #11 클로저(Closure) 5분만에 이해하기
[10분 테코톡] 🍧 엘라의 Scope & Closure

피드백은 언제든 환영합니다 🙏

profile
정보를 공유하겠습니다 😀

0개의 댓글