[JavaScript] 9. 클로저

Hyun Jin·2023년 1월 2일
0

JavaScript

목록 보기
10/20
post-thumbnail

🚪 클로저


  • 정의 : 함수와 함수가 선언된 어휘적(lexical) 환경의 조합. 이 환경은 클로저가 생성된 시점의 유효 범위 내에 있는 모든 지역 변수로 구성됨.
  • 자바스크립트는 함수가 호출되는 환경과 별개로 기존에 선언되어 있던 환경, 즉 어휘적 환경(lexical)을 기준으로 변수를 조회하려고 함.
  • 클로저 함수 : 외부 함수의 변수에 접근할 수 있는 내부 함수

클로저 MDN 페이지 정의

  • A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function's scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.

📋 학습 목표

  • 클로저 함수의 정의와 특징에 대해서 이해할 수 있다.
  • 클로저가 갖는 스코프 범위를 이해할 수 있다.
  • 클로저를 이용해 유용하게 쓰이는 몇 가지 패턴을 이해할 수 있다.

📖 1. 클로저 함수의 특징


1-1. 함수를 리턴하는 함수 (함수 내부의 함수 실행 결과를 리턴함)

  • 클로저는 리턴하는 함수에 의해 스코프(변수의 접근 범위)가 구분됨.
  • 클로저의 핵심은 스코프를 이용해서 변수의 접근 범위를 닫는(closure; 폐쇄) 데에 있음.
    따라서, 함수를 리턴하는 것만큼이나 변수가 선언된 곳이 중요함.

✳️ MDN example code :

function init() { // init 함수는 또 다른 함수를 리턴하고 있으므로 클로저 함수임.
    const name = 'Mozilla'; // name is a local variable created by init

    function displayName() {
      // displayName() is the inner function, a closure
      console.log(name); // use variable declared in the parent function
      }
    }
    displayName();
  }
init();

✳️ 어휘적 환경(lexical environment) :

  • 변수 및 함수 선언의 형태.
  • 함수를 어디서 선언(생성)하였는지에 따라 상위 스코프를 결정한다는 뜻(함수를 호출한 곳이 아니라 함수를 선언한 곳에 따라 결정됨!!)
  • 정적 스코프(Static scope) 라고 부르기도 함.(<> Dynamic Scope)
    (In static scope, variables are referenced in a context at the time of creation. Whereas in dynamic scope, variables are referenced at the run time.)

✳️ 스코프 체인(scope chain)

  • 일종의 리스트로서 전역 객체와 중첩된 함수의 스코프의 레퍼런스를 차례로 저장하고, 의미 그대로 각각의 스코프가 어떻게 연결(chain)되고 있는지 보여주는 것

✳️ 정리

  • 외부 함수(바깥쪽 스코프) -> 내부 함수(안쪽 스코프) 접근 불가, 안쪽 스코프 -> 바깥쪽 스코프에서 선언된 변수에 접근 가능.

✳️ 추가 의문

❓ : 내부 함수는 바로 위 외부 함수(부모 함수)의 스코프에만 접근이 가능한가?

     ⇨ ❌! 내부 함수는 모든 외부 함수 스코프에 접근이 가능함.
   내부 함수가 위치한 전체 함수 스코프에도 변수 명이 없으면 전역 스코프(Global scope)까지 탐색함!
   (단 같은 이름의 변수가 여러 단계에서 재할당 되었을 경우, 가장 가까운 상위 스코프의 변수명의 값을 가져오고 내부함수가 종료되어 그 이상의 상위 스코프를 탐색하지 않음)

  • 전역 스코프에 설정된 'name' 을 참조하는 내부 함수 예시
 let name = 'Mozilla';
function init() {
    function displayName() {
      return function () {
        return function () {
            console.log(name);
          }
      }
    }
    return displayName()()(); // 결과값 : 'Mozilla'
  }
init();
  • var, let, const 는 모두 함수 스코프를 가질 수 있으므로 동일하게 적용됨.

❓ : 내부 함수는 왜, 어떻게 외부 스코프의 변수를 참조 가능한가?
❗️ : 내부 함수 innerFunc()가 호출될 때, 외부 함수 outerFunc()의 환경(Lexical environment)을 기억하고 있기 때문!
즉, 클로저(closure)는 반환된 내부 함수가 자신이 선언(생성)되었을 때의 환경(Lexical environment)인 스코프를 기억하여, 자신이 선언됐을 때의 환경(스코프) 밖에서 호출되어도 그 환경(스코프)에 접근할 수 있는 함수임.

✒️ 참고자료

🔗 Closure in JavaScript - scaler.com


1-2. 외부 함수의 변수에 접근 가능한 내부 함수


📖 2. 클로저의 활용


1. 데이터를 보존하는 함수

  • 일반적인 함수와는 다르게, 클로저는 외부 함수의 실행이 끝나더라도 외부 함수 내의 변수가 메모리에 저장되어 사용할 수 있음.(lexical environment 를 메모리에 저장하기 때문!)
  • 그래서 특정 변수를 넣고 실행한 클로저 함수의 결과값을 다른 변수에 할당할 수 있음.
const tagMaker = tag => content => `<${tag}>${content}</${tag}>`;
const divMaker = tagMaker('div');
console.log(divMaker('hello')); // 결과값 : <div>hello</div>
console.log(divMaker()); // 결과값 : <div>undefined</div>

=> 클로저 함수인 tagMaker'div' 변수가 저장되어, 외부함수 실행은 끝났지만 계속해서 출력 가능

2. 클로저 모듈 패턴

===> 여기서부턴 내일 정리하자 @_@ 연습문제 풀다보니 아직 제대로 이해가 안되었다! 변수가 어디로 들어가는지 헷갈림...!


📚 추가로 공부할 것 :

  • 화살표 함수 다시 보기
profile
새싹 프론트엔드 개발자

0개의 댓글