[JS] 클로저 (Closure)

Chaewon·2023년 1월 23일
0

코드스테이츠

목록 보기
9/10

클로저

클로저는 함수와 함수가 선언된 어휘적(lexical)환경의 조합을 말한다. 이 환경은 클로저가 생성된 시점의 유효 범위 내에 있는 모든 지역 변수로 구성된다.

자바스크립트는 함수가 호출되는 환경과 별개로 기존에 선언되어 있던 환경, 즉 어휘적 환경을 기준으로 변수를 조회하려고 한다. 이와 같은 이유로 외부 함수의 변수에 접근할 수 있는 내부 함수를 클로저 함수라고 한다.

클로저 함수 특징

1. 함수를 리턴하는 함수

const adder = (x, y) => x + y;
adder(5, 7); // 12

// 함수의 호출(invocation)이 두 번 발생
const adder = x => y => x + y;
adder(5)(7); // 12

adder(5)의 리턴 값이 함수의 형태. 즉, adder는 함수를 리턴하는 함수이다.

typeof adder(5); // 'function'
adder(5) // y => x + y // (x = 5)

function 키워드 이용하면 다음과 같다

function adder = function(x) {
  return function(y) { // 리턴값이 함수 형태
    return x + y;
  }
}

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

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

const adder = function(x) { // 외부함수
   return function(y){  // 내부함수
     return x + y;
   }
}
  • 외부함수는 y에 접근이 가능한가? -> 바깥 스코프에서는 안쪽 스코프 접근불가
  • 내부함수는 x에 접근이 가능한가? -> 바깥 스코프에서 선언한 변수 접근 가능

    클로저 함수는 내부 함수는 외부 함수에 선언된 변수에 접근이 가능하다

클로저 활용

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

외부 함수(adder)의 실행이 끝나더라도, 외부 함수 내 변수(x)를 사용할 수 있다.

const adder = function(x){
  return function(y){
    return x + y;
  }
}
const add5 = adder(5); // 함수 실행이 끝나도, 5라는 값은 사용 가능
add5(7); // 12
add5(10); // 15

일반적인 함수는 함수 실행이 끝나고 나면 함수 내부의 변수를 사용할 수 없다,
반면에 클로저는 외부 함수의 실행이 끝나더라도, 외부 함수 내 변수가 메모리 상에 저장된다.(어휘적 환경을 메모리에 저장하기 때문)

cosnt tagMaker = tag => content => `<${tag}>${content}</${tag}>`

const divMaker = tagMaker('div');
divMaker('hello'); // <div>hello</div>
divMaker('codestates'); // <div>codestates</div>

cosnt anchorMaker = tagMaker('a');
anchorMaker('go'); // <a>go</a>
anchorMaker('urclass'); // <a>urclass</a>

클로저는 이처럼 특정 데이터를 스코프 안에 가두어 둔 채로 계속 사용할 수 있게 해준다.

2. 클로저 모듈 패턴

const makeCounter = () => {
  let value = 0;
  
  return {
    increase: () => {
      value = value + 1;
    },
    decrease: () => {
      value = value - 1;
    },
    getValue: () => value
  }
}  

const counter1 = makeCounter();
console.log(counter1()) // {increase : f, decrease, f, getValue f}

클로저를 이용해 객체에 대한 여러 개의 내부 함수를 리턴하도록 한다.

const counter1 = makeCounter();
counter1.increase(); // 1
counter1.increase(); // 2
counter1.decrease(); // 1

counter1.getValue(); // 1

const counter2 = makeCounter();
counter2.decrease(); // -1
counter2.decrease(); // -2
counter2.decrease(); // -3

counter2.getValue(); // -3

counter1 과 counter2의 value는 서로 영향을 끼치지 않는다

함수 재사용성을 극대화하여, 함수 하나를 완전히 독립적인 부품형태로 분리하는 것을 모듈화라고 한다.
클로저를 통해 데이터와 메서드를 같이 묶어서 다룰 수 있다.


즉, 클로저는 모듈화에 유리하다

profile
가보자고💪

0개의 댓글