본문 바로가기

FE(front-end)

[자바스크립트] 클로저(closure)

1급 객체란

아래 3가지 조건을 모두 충족하면 1급 객체라고 한다.

 

조건1, 변수나 데이터에 담을 수 있어야 한다.

조건2, 함수의 파라미터(객체의 인자)로 전달될 수 있어야 한다.

조건3, 함수(객체)의 리턴값으로 사용 할 수 있어야 한다.

1. 클로저(closure)

클로저는 자바스크립트 고유의 개념이 아니라 함수를 일급 객체로 취급하는 함수형 프로그래밍 언어(Functional Programming language: 얼랭(Erlnag), 스칼라(Scala), 하스켈(Haskell), 리스프(Lisp)…)에서 사용되는 중요한 특성이다.

 

자신을 포함하고 있는 외부함수보다 내부함수가 더 오래 유지되는 경우, 외부 함수 밖에서 내부함수가 호출되더라도 외부함수의 지역 변수에 접근할 수 있는데 이러한 함수를 클로저(Closure)라고 부른다.

즉, 특정한 함수가 종료되어도 내부 지역변수가 남는다.

 

2. 클로저 이해를 위한 자바스크립트 함수자체 리턴, 함수 호출 결과 리턴

1.함수 자체를 리턴하는 케이스

// 자바스크립트의 함수는 함수를 리턴할 수 있음
// 자바스크립트에서 함수 분류 시 first-class인 1급 객체라고 부른다.
function calculator(n1,n2){
    // 함수를 변수처럼 선언 및 변수처럼 return 가능
    function add(){ // 함수 내부 지역에서 사용하는 내부 함수
        return n1+n2;
    }
    // 함수 자체를 리턴하는 케이스
    // return add;
}

// 1. 함수 자체를 리턴하는 케이스
// n1+n2를 실행한다 X, add라는 함수를 정의만 한 상태
// closur == add , add 호출 X
const closur = calculator(5,6); 
console.log(closur);
console.log(typeof(closur));

 

  2. 함수를 호출한 결과를 리턴하는 케이스

// 자바스크립트의 함수는 함수를 리턴할 수 있음
// 자바스크립트에서 함수 분류 시 first-class인 1급 객체라고 부른다.
function calculator(n1,n2){
    // 함수를 변수처럼 선언 및 변수처럼 return 가능
    function add(){ // 함수 내부 지역에서 사용하는 내부 함수
        return n1+n2;
    }
    // 함수를 호출한 결과를 리턴하는 케이스
    return add();
}

// 2. 함수를 호출한 결과를 리턴하는 케이스
// calculator 지역 내부의 위치하여 접근 가능해서 add()로 파라미터는 가까운 변수를 가져와 씀.
// closur에 11을 저장한다.
const closur = calculator(5,6); 
console.log(closur);
console.log(typeof(closur));

 

3. 클로저 이점

3.1 상태 유지 

클로저가 가장 유용하게 사용되는 상황은현재 상태를 기억하고 변경된 최신 상태를 유지하는 것이다.

ex) 리액트에서 status, setStatus

 

3.2 정보의 접근 제한 캡슐화

‘클로저 모듈 패턴’을 사용해 객체에 담아 여러 개의 함수를 리턴하도록 만든다. 이러한 정보의 접근을 제한하는 것을 캡슐화라고 한다.

 

3.3 전역변수 사용량 감소

 

4. 클로저 사용 예시

4.1 클로저 적용 코드

// 1. 함수 자체 반환
function getVisitor(){
    let visitCount = 0; // 지역변수이지만, 호출이 끝나도 값을 유지하고 있음
    function countVisitor(){
        return ++visitCount
    }
    return countVisitor;
}

// 클로저 적용 코드 (getVisitor가 종료되어도 계속해서 visitCount의 값이 유지됨)
const countVisitor1= getVisitor();
console.log(countVisitor1());
console.log(countVisitor1());
console.log(countVisitor1());

 

4.2 클로저 미 적용 코드

// 2. 함수 결과값 반환
function getVisitor(){
    let visitCount = 0; // 지역변수로 호출이 끝나면 사라짐.
    function countVisitor(){
        return ++visitCount
    }
    return countVisitor();
}

// 클로저 미 적용 코드(getVisitor() 호출시마다 visitCount가 0으로 초기화됨)
// 호출이 끝나고 초기화 되는 과정이 진행되면서 1에서 늘어나지 않은 = 결과값 반환임으로
const countVisitor2= getVisitor();
console.log(countVisitor2); 

const countVisitor3= getVisitor();
console.log(countVisitor3);