클로저 함수 (closure)

hoin_lee·2023년 8월 16일
0

TIL

목록 보기
213/236

오늘 교육기관 합류를 위한 레벨테스트를 봤는데 생각보다 CS 지식 부분에서 순간순간 막히는 부분이 있었던 것 같다
문제를 풀어보며 기초적인 지식과 javscript의 딥다이브가 많이 부족하구나 느꼈는데
closure가 머릿속에서 아예 없었다는 게 아쉬웠다
이전에 한번 til로 다뤘지만 추가적인 부분이 있으면 좋을 것 같다

클로저 함수

먼저 장점부터 살펴보자

  • 데이터를 보존할 수 있다
    • 클로저 함수는 외부 함수의 실행이 끝나더라도 외부 함수 내 변수를 사용할 수 있다
    • 클로저는 이처럼 특정 데이터를 스코프 안에 가두어 둔 채로 계속 사용할 수 있게 하는 폐쇄성을 갖는다
  • 정보의 접근 제한(캡슐화)
    • 클로저 모듈 패턴을 사용해 객체에 담아 여러 개의 함수를 리턴하도록 만드는데 이러한 정보의 접근을 제한하는 것을 캡슐화라고 한다
  • 모듈화에 유리
    • 클로저 함수를 각각의 변수에 할당하면 각자 독립적으로 값을 사용 보존 할 수 있다
      이와 같이 함수의 재사용성을 극대화, 함수 하나를 독립적인 부품의 형태로 분리하는 것을 모듈화라고 한다.
      클로저를 통해 데이터와 메소드를 묶어 다닐 수 있기에 클로저는 모듈화에 유리하다

클로저 정의

함수와 함수가 선언된 어휘적(lexical)환경의 조합

  • 클로저는 함수를 지칭하고 또 그 함수가 선언된 환경과의 관계라는 개념이 합쳐진 것

클로저의 핵심은 스코프를 이용해서, 변수의 접근 범위를 닫는(폐쇄)것에 있다

  • 외부 함수 스코프에서 내부 함수 스코프로 접근 불가능
  • 내부함수에서는 외부 함수 스코프에서 선언된 변수에 접근 가능하다
  • 내부 함수는 외부 함수에 선언된 변수에 접근 가능

함수가 호출되는 환경과 별개로, 기존에 선언되어 있던 환경(어휘적 환경)을 기준으로 변수를 조회한다

  • 외부 함수의 실행이 종료된 후에도, 클로저 함수는 외부함수의 스코프, 즉 함수가 선언된 어휘적 환경에 접근할 수 있다
  • 외부 함수 스코프가 내부 함수에 의해 언제든지 참조될 수 있다
  • 따라서 클로저를 남발할 경우 퍼포먼스 저하가 발생할 수도 있다

**상위 스코프의 식별자를 포함하여 쓰여있는 내부 함수 코드 자체를 어휘적 환경(lexical environment)라고 부를 수 있다

이해가 안가는 부분

클로저는 내부 함수가 외부 함수의 맥락(context)에 접근할 수 있는 것을 가리킨다?

  • 내부함수(innerFn)가 상위 스코프(outerFn)의 식별자를 참조하고 있고, 그 내부함수(innerFn)를 그 상위 스코프(outerFn) 바깥에서 사용했을 때, 그 상위 스코프(outerFn)의 식별자를 수정할 수 없는 형태이다.
  • 즉, 함수가 정의되었던 위치에서 상위 스코프(outerFn)식별자를 기억하고 있는 형태이다.
  • 그래서 중첩함수 뿐만 아니라 내부함수가 외부 스코프에 접근할 수 있는 형태의 클로저도 존재한다.

그래도 잘 이해가 안되는데 예시를 봐보자

// 클로저를 만드는 형태 1. - 중첩함수
function outerFn() {
  let x = 10;
  return function innerFn(y) { // innerFn 함수는 클로저다.
    return x = x + y;
  }
}
let a = outerFn(); // 외부함수 호출은 한번만. 이제 a 변수는 innerFn 함수를 참조한다.
a(5); // 15;
a(5); // 20;
a(5); // 25;
// 클로저를 만드는 형태 2. - 전역에 선언한 변수를 박스 안에서 함수로 정의하고 전역에서 호출
let globalFunc;
{
  let x = 10;
  globalFunc = function(y) { // globalFunc 함수는 클로저다.
    return x = x + y;
  }
}
globalFunc(5); // 15;
globalFunc(5); // 20;
globalFunc(5); // 25;

예시를 보며 코드 흐름을 따라갔더니 드디어 이해가 됐다.

클로저는 함수를 리턴하는 함수?

  • 클로저가 언제나 함수를 리턴하는 것은 아니다
(function () {
    var count = 0;
    var button = document.createElement("button");
    button.innerText ="click";
    button.addEventListener("click", function() {
        console.log(++count, "times clicked")
    })
    document.body.appendChild(button)
})();
// 별도의 외부객체인 DOM의 메서드(addEventListener)에 등록할 handler함수 내부에서 지역변수를 참조!

지역 변수를 참조하는 내부 함수를 외부에 전달했기에 클로저는 맞지만,"외부로 전달"이 항상 return을 의미하는 것은 아니다라고 생각하자

클로저는 외부함수와 내부함수에 의해서 스코프가 분리된다?

  • 외부함수와 내부 함수에 의해 스코프가 분리된 클로저가있다 가 맞다
  • 박스와 내부함수에 의해 스코프가 분리된 클로저도 있다

Reference

profile
https://mo-i-programmers.tistory.com/

0개의 댓글