자바스크립트에서 클로저란

Jin·2022년 3월 1일
0

Javascript

목록 보기
9/22

클로저는 렉시컬 스코프에 의존해 코드를 작성한 결과로 그냥 발생합니다.

여기서, 렉시컬 스코프란 개발자가 코드를 작성할 때 함수를 어디에 선언하는지에 따라 정의되는 스코프입니다.

모든 코드에서 클로저는 생성되고 사용됩니다.

function foo() {
  var a = 2;
  function bar() {
    console.log(a); // 2
  }
  bar();
}

foo();

함수 bar()는 렉시컬 스코프 검색 규칙을 통해 바깥 스코프의 변수 a에 접근할 수 있습니다. (이 경우에는 RHS 참조 검색)

여기서 클로저의 마법이 발생하는 것입니다.

선언된 위치 덕에 bar()는 foo() 스코프에 대한 렉시컬 스코프 클로저를 가지고 foo()는 bar()가 나중에 참조할 수 있도록 스코프를 살려둡니다. 즉, bar()는 여전히 해당 스코프에 대한 참조를 가지는데, 그 참조는 바로 클로저라고 부릅니다.

여기서 알 수 있듯이 클로저는 호출된 함수가 원래 선언된 렉시컬 스코프에 계속해서 접근할 수 있도록 허용합니다.

어떤 방식으로 내부 함수를 자신이 속한 렉시컬 스코프 밖으로 꺼냈든지간에 함수는 처음 선언된 곳의 스코프에 대한 참조를 유지하므로 어디에서 해당 함수를 실행하든 클로저가 작용하는 것입니다.

클로저를 우리는 자바스크립트 모듈에 활용할 수 있습니다.

function Module() {
  var something = "hot";
  var another = [1, 2, 3];

  function doSomething() {
    console.log(something);
  }

  function doAnother() {
    console.log(another.join(" ! "));
  }

  return {
    doSomething: doSomething,
    doAnother: doAnother
  }
}

var foo = Module();
foo.doSomething(); // hot
foo.doAnother(); // 1 ! 2 ! 3

위의 코드와 같은 패턴을 모듈이라고 합니다.

Module()은 그저 하나의 함수이지만, 모듈 인스턴스를 생성하려면 반드시 호출하여야 합니다.

Module() 함수는 객체를 반환합니다. 해당 객체는 내장 함수들에 대한 참조를 가지지만, 내장 데이터 변수에 대한 참조는 가지지 않습니다. 내장 데이터 변수는 비공개로 숨겨져 있는 것입니다.

여기서 우리는 모듈 패턴을 사용하려면 두 가지 조건이 있다는 것을 알 수 있습니다.

  • 하나의 최외곽 함수 (여기서는 Module 함수)가 존재하고, 이 함수가 최소 한 번은 호출되어야 한다. (호출해야 모듈 인스터스가 생성되므로)
  • 최외곽 함수는 최소 하나의 내부 함수를 반환해야 한다. 그래야 해당 내부 함수가 비공개 스코프에 대한 클로저를 가져 비공개 상태에 접근하고 수정할 수 있다.

위의 코드는 호출할 때마다 새로운 모듈 인스턴스를 생성하지만 오직 하나의 인스턴스만 생성하는 모듈인 싱글톤 코드도 위와 크게 다르지 않습니다.

var foo = (function Module() {
  var something = "hot";
  var another = [1, 2, 3];

  function doSomething() {
    console.log(something);
  }

  function doAnother() {
    console.log(another.join(" ! "));
  }

  return {
    doSomething: doSomething,
    doAnother: doAnother
  }
})();

foo.doSomething();
foo.doAnother();

즉시 실행 함수로 모듈을 즉시 실행시켜 반환 값을 직접 변수 foo에 대입시키는 것입니다.

ES6에서는 파일을 개별 모듈로 처리하기 때문에 우리는 쉽게 함수나 변수를 import하거나 export하여 하나 이상의 멤버를 불러오거나 내보낼 수 있습니다.

클로저는 표준이고 함수를 값으로 넘길 수 있는 렉시컬 스코프 환경에서 코드를 작성하는 방법입니다.

클로저는 함수를 렉시컬 스코프 밖에서 호출해도 함수는 자신의 렉시컬 스코프를 기억하고 접근할 수 있는 특성을 의미합니다.

profile
배워서 공유하기

0개의 댓글