코딩/정말 나는 잘 알고 있을까?

클로저(Closure)가 뭐야?

호상박 2022. 8. 2. 03:45

클로저(Closure)

함수와 함수가 선언된 어휘적 환경의 조합이다. 클로저를 이해하려면 자바스크립트가 어떻게 변수의 유효범위를 지정하는지(Lexical scoping)를 먼저 이해해야 한다.

 

- 어휘적 범위 지정 (Lexical scoping)

function init() {
  var name = "test";
  function displayName() {
    console.log(name);
  }
  displayName();
}
init();

여기서 주의할 점은 displayName() 내부에는 자신만의 지역 변수가 없다는 점이다. 하지만 함수 내부에서 외부 함수의 변수에 접근할 수 있기 때문에 displayName() 역시 부모 함수 init() 에서 선언된 변수 name에 접근할 수 있다. 만약 displayName() 이 자신만의 name 변수를 가지고 있었다면, name 대신 this.name을 사용했을 것이다.

test

 

그렇다면 클로저를 알아보자.

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

var add5 = makeAdder(5);
var add10 = makeAdder(10);
// 클로저에 x와 y의 환경이 저장됨

console.log(add5(2));
console.log(add10(2));
// 함수 실행 시 클로저에 저장된 x, y값에 접근하여 값을 계산

복잡해 보이지만 하나하나 뜯어보면 답을 알 수 있다.

이 예제는 단일 인자 x를 받아서 새 함수를 반환하는 makeAdder(x)를 정의한다. 또 반환되는 함수는 단일인자 z를 받아서 x와 y와 z의 합을 반환한다.

add5와 add10은 둘 다 클로저이다. 이들은 같은 함수 본문 정의를 공유하지만 서로 다른 맥락(어휘)적 환경을 저장한다. 함수 실행 시 add5의 맥락적 환경에서 클로저 내부의 x는 5이지만, add10의 맥락적 환경에서 x는 10이다. 또한 리턴되는 함수에서 초기값이 1로 할당된 y에 접근하여 y값을 100으로 변경한 것을 볼 수 있다. (물론 x값도 동일하게 변경 가능하다.) 이는 클로저가 리턴된 후에도 외부함수의 변수들에 접근 가능하다는 것을 보여주는 포인트이며 클로저에 단순히 값 형태로 전달되는 것이 아니라는 것을 의미한다.

 

따라서 다음과 같은 값을 출력한다.

107 // (x:5 + y:100 + z:2)
112 // (x:10 + y:100+ z:2)

 

위와 같은 방식으로 자바스크립트에는 없는 캡슐화라는 개념을 구현할 수 있고, 정보 은닉과 캡슐화가 가져다주는 이점들을 얻을 수 있다.

 

https://github.com/Esoolgnah/Frontend-Interview-Questions/blob/main/Notes/important-5/closure.md#gear-%EB%A0%89%EC%8B%9C%EC%BB%AC%EC%8A%A4%EC%BD%94%ED%94%84

 

GitHub - Esoolgnah/Frontend-Interview-Questions: 프론트엔드 중요도별 면접질문 + 용어 설명 ⭐️

프론트엔드 중요도별 면접질문 + 용어 설명 ⭐️. Contribute to Esoolgnah/Frontend-Interview-Questions development by creating an account on GitHub.

github.com

https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures

 

클로저 - JavaScript | MDN

클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다. 클로저를 이해하려면 자바스크립트가 어떻게 변수의 유효범위를 지정하는지(Lexical scoping)를 먼저 이해해야 한다.

developer.mozilla.org