클로저?

클로저를 MDN에서는 "함수와 함수가 선언된 어휘적 환경의 조합이다" 라고 정의하고 있다. 전혀 이해가 되지 않는다. 사실 클로저를 이해하기 위해서는 먼저 위의 정의에 나온 어휘적 환경의 개념을 알고 있어야 한다. 그렇다면 클로저는 무엇이고 어휘적 환경은 무엇이며 그들의 관계가 무엇인지 알아보도록 하자.

 

Lexical Scope

정적 유효 범위라고도 하며 이게 바로 앞서 언급한 어휘적 환경이다. 자바스크립트는 코드가 적힌 순간 변수들의 유효 범위가 정해지며, 중첩된 함수에서 내부 함수는 외부 함수의 변수에 접근할 수 있다. 아래 코드를 보자.

 

function outerFunc() {
  // the outer scope
  let outerVar = 'I am outside!';

  function innerFunc() {
    // the inner scope
    console.log(outerVar); // 'I am outside!'
  }

  innerFunc();
}

outerFunc();

 

 

위의 코드를 실행시키면 innerFunc()에서 외부 함수의 변수인 outerVar를 문제 없이 출력한다. 이는 정적 유효 범위이자 Lexical Scope의 예시로서, 중첩된 함수에서 parser가 어떻게 변수를 처리하는지 알 수 있다. 위의 예에서 알 수 있듯이 내부 함수는 외부 함수에서 선언한 변수에 접근을 할 수 있다. 다른 예시를 살펴보자.

 

let name = 'ginger';
function print() {
  console.log(name); // kang
}

function main() {
  name = 'kang';
  print();
}

main();

 

위에서 전역 변수인 namemain()에서 'kang'으로 갱신 시켜주었으므로 로그에는 'kang'이 찍힌다. 

 

var name = 'ginger';
function print() {
  console.log(name); // ginger
}

function main() {
  var name = 'kang';
  print();
}

main();

 

 

위 코드는 main()에서 name변수를 똑같은 이름으로 함수 스코프의 지역 변수를 선언했다. 이렇게 되면 'kang'을 가지는 namemain()함수를 벗어나지 못하므로 로그에는 'ginger'가 찍히게 된다.

 

Closure

그렇다면 클로저는 무엇일까? 

 

function outerFunc() {
  // the outer scope
  let outerVar = 'I am outside!';

  function innerFunc() {
    // the inner scope
    console.log(outerVar); // 'I am outside!'
  }

  return innerFunc;
}

const myInnerFunc = outerFunc();
myInnerFunc();

 

위의 코드는 첫 번째 예시와 동일한 결과가 실행된다. 달라진 점은 myInnerFunc라는 변수에 outerFunc함수를 저장했다는 것이다. 이때, outerFunc에서 리턴하는 함수 innerFunc은 내부 함수이자, 클로저라 할 수 있다. innerFunc은 변수 outerVar가 가지고 있는 정적 유효 범위를 유지한 채 리턴이 된다.

 

 

위의 그림과 같이 innerFunc클로저를 생성하며 outerVar을 캡쳐해 놓는다고 생각을 하면 된다.

 

function multiply(a) {
  return function executeMultiply(b) {
    return a * b;
  }
}

const double = multiply(2);
double(3); // => 6
double(5); // => 10

const triple = multiply(3);
triple(4); // => 12

 

위의 예에선 executeMulfiply클로저이며, multiplya를 캡쳐한다. 따라서 위의 코드가 정상 작동되는 것을 볼 수 있다.

 

참고

Dmitri Pavlutin의 'A Simple Explanation of JavaScript Closures'

 

 


생강강

,