[javascript] 클로저 / closure

kaya·2023년 8월 18일

Javascript

목록 보기
3/13

클로저란?

함수 객체와 scope를 조합한 것!!

  • 정의가 다소 추상적인데 아래 특징과 사용법을 보면 이해가 갈 것이다

더 자세히 설명해보자

함수가 정의된 곳과 다른 scope에서 호출될 때 사용한다

function closureFunc() {
	let n = 0;
  	return function () {
    	return n++;
    }
}

let s = closureFunc();
let n = closureFunc();
s(); // 1
s(); // 2

n(); // 1
n(); // 2
  • 변수 sclosureFunc 함수와 다른 scope인 전역 scope에서 선언되었다.
  • 함수 내부의 변수 n은 함수 scope 밖에서는 접근할 수 없는 것이 맞지만
  • 클로저는 함수 호출 시점의 local 변수를 "캡쳐"하기 때문에 closureFunc의 리턴값인 함수가 할당된 변수 s를 통해 n에 접근할 수 있는 것이다.

클로저의 특징

클로저는 함수 호출 시점의 로컬 변수를 캡쳐한다
➡️ 클로저와 연관된 scope는 다른 scope에 가서도 살아 있다
➡️ 함수는 만들어진 환경을 '기억한다'

  • 위 예시에서 보면 변수s에는 closureFunc 함수 객체가 할당되었다
    ➡️ 이 s에는 closureFunc의 리턴문인 함수가 할당되어 있고, 함수 호출 시점의 로컬 변수도 캡쳐되어 있기 때문에 n에 접근할 수 있다.
  • 또, closureFunc() 함수는 호출될 때마다 새로운 함수 객체가 생성되는 것이기 때문에
    ➡️ n은 다시 1부터 시작하는 것이다

클로저를 사용할 때

  1. 대부분 함수의 리턴문이 함수일 때 사용한다 ➡️ 그래야 외부에서 내부의 scope에 접근할 수 있기 때문이다.
    • 객체로 리턴하기도 한다 ➡️ 이렇게 하면 .으로 접근할 수 있다.
    function closureFunc() {
        let n = 0;
        return {
            count: function () {return n++;},
    		getNum: function() {return n}
        }
    }
    let s = closureFunc();
    s.count(); // 1
    s.count(); // 2
    s.getNum() // 2
  2. getter, setter과 함께 사용해서 외부에서 객체 내부 변수에 접근하려 할 때
  • 객체 내부 변수를 비공개 상태로 외부 scope에서 마음대로 접근할 수 없게 할 수 있음
    ➡️ encapsulation
function counter(n) {
	return {
    	get count() {return n++}
      	set count(m) { n = m;}
    }
}

let s = counter(10);
s.count(); // 11
s.count(12) // n = 12로 set
  • get set: js의 접근자 프로퍼티
  • java에서 클래스 내부 변수에 직접 접근하지 않고 getter, setter를 통해서 접근하게 하는 것과 같다

비공개 변수
- 그 변수가 선언된 scope 밖에서 접근할 수 없는 변수
- 즉, .으로 접근이 안되는 변수


문제점

  • 접근을 공유하면 안되는 변수에 대한 접근까지 부주의하게 공유할 수도 있다



참고 자료

자바스크립트 완벽 가이드/ 데이비드 플래네건 지음/ 한빛미디어, O'REILLY
Javascript 클로저(Closure)

profile
🏟 튼튼한 성은 튼튼한 벽돌로부터

0개의 댓글