[JS] 클로저

HP :) 😃·2022년 8월 10일
0
post-thumbnail

안녕하세요 hp입니다 :)

오늘은 자바스크립트의 중요한 개념중의 하나인 클로저에 대해서 공부해보겠습니다.

📚 개념

클로저를 이해하기에 앞서 먼저 Lexical Scoping에 대해서 알아보겠습니다.

Lexical Scoping

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

위에 예제는 MDN에 나와있는 Lexical scoping에 예제입니다.
저희는 debugger를 통해서 어떻게 동작되는지 자세히 알아보겠습니다. ScopeCall Stack을 자세히 봐주세요.

자바스크립트를 실행하게 되면 anonymous( 전역 컨텍스트 )가 Call Stack에 쌓이게 되고 init() 함수를 통해서 init()을 Call Stack에 저장하고 내부로 들어가 name 값을 init의 Local Scope 변수로 갖고 있습니다.

그리고 displayName()을 만나서 displayName()을 Call Stack에 저장하고 내부로 들어가게 되면 현재 displayName에는 선언된 지역변수가 없지만 Closure Scope내에 name이라는 변수에 Mozilla라는 값을 갖고 있는 것을 볼 수 있습니다.

위와 같은 과정을 통해서 alert 문이 name 값을 성공적으로 출력하는 것을 볼 수 있고 함수가 중첩된 상황에서 파서는 자신이 선언된 위치를 기준으로 자신의 scope에서 먼저 해당 값을 찾고 -> 자신을 포함하는 외부에서 찾고 -> 마지막으로 전역에서 변수를 찾게 됩니다. 이를 Lexical scoping이라고 합니다.

Closure

Lexical Scope에 대해서 알아봤으니 이제 본격적으로 Closure에 대해서 알아보겠습니다.

Closure란 외부 함수 호출이 종료되었음에도 외부 함수 및 변수에 접근할 수 있는 것을 말합니다.

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

var myFunc = makeFunc();

myFunc();

위에 예제는 처음 봤던 예제와 동일한 결과값을 내는 Closure 예제입니다.

직관적으로 코드를 들여다보면 var myFunc = makeFunc()를 통해서 displayName 함수를 리턴하게 되면 myFunc()를 호출할 때 name에 접근하지 못할 것으로 예상되지만 자바스크립트는 함수를 리턴하고 리턴하는 함수가 클로저를 형성하기 때문에 위와 같은 상황이 가능합니다.

위 예제 또한 debugger를 통해 자세히 보겠습니다.

먼저 makeFunc() 함수를 호출하게 되면 Call Stack에 올라가게 되고 makeFunc 함수 내부에는 name이라는 값을 지역 스코프로 갖고 있는 것을 볼 수 있습니다. 그리고 displayName 함수를 리턴하게 되고 makeFunc는 Call Stack에서 지워지게 됩니다.

myFunc를 호출했을때 displayName이 Call Stack에 올라가고 Closure 스코프안에 name값이 정의되고 displayName 함수 안에서 alert 창을 띄울때 name 값을 알 수 있게 됩니다.

또 다른 예시를 살펴보겠습니다.

function makeAdder(x) {
  var y = 1;
  return function (z) {
    y = 100;
    return x + y + z;
  };
}

var add5 = makeAdder(5);
var add10 = makeAdder(10);

console.log(add5(2));
console.log(add10(2));

위 예제를 보고 먼저 답을 고민해보시고 읽어주시면 좋을 것 같습니다. 😃
위 예제들이랑 똑같이 debugger를 통해서 살펴보겠습니다.

먼저 makeAdder(5)를 통해서 makeAdder 함수에 들어가게 되면 makeAdder는 Call Stack에 쌓이게 되고 Local Scope로 x=5와 y=1의 값을 갖고 있습니다.

그리고 add5(2)에 접근하게 되면 makeAdder 함수의 return 문이 실행되고 이때 함수 이름이 정의되어 있지 않으니까 anonymous 함수가 Call Stack에 쌓이고 z를 Local Scope로 갖고 x=5와 y=1을 Closure Scope로 갖고 있습니다.

이후에 y=100을 만나서 Closure Scope의 y값이 100으로 바뀌고 결국에는 x=5 y=100 z=2를 더해서 107의 결과값을 console에 찍게 됩니다.

끝까지 읽어주셔서 감사합니다. 😃

📌 참고

MDN 클로저

profile
끊임없이 노력하는 개발자

0개의 댓글