클로저
- 함수와 그 함수가 선언된 렉시컬 환경의 조합
- 어떤 함수가 선언된 당시의 환경을 기억하여, 함수가 실행될 때에도 그 환경에 접근할 수 있게 해준다
- 데이터를 은닉하고 캡슐화하는 데 유용하게 사용됨
function 외부함수(외부변수) {
return function 내부함수() {
console.log(외부변수);
};
}
const 예제 = 외부함수('안녕하세요!');
예제(); // 콘솔에는 '안녕하세요!'가 출력됩니다.
예제 코드에서 외부함수는 내부함수를 생성하고 반환한다
내부함수는 외부함수의 매개변수인 외부변수에 접근할 수 있다
이처럼 내부함수가 자신이 생성될 때의 환경(여기서는 외부변수를 포함하는 환경)을 기억하는 것이 클로저의 핵심 개념이다
예제()를 호출하면 외부함수의 실행 컨텍스트가 이미 종료되었음에도 내부함수는 여전히 외부변수에 접근할 수 있다
함수가 자신이 선언될 때의 변수와 환경을 기억하며, 이러한 환경에는 해당 함수의 매개변수, 지역 변수, 그 외부 환경의 변수들이 포함될 수 있다
함수가 자신이 선언될 때의 변수와 환경을 기억하는 것만으로 클로저라고 정의하는 것이 아니라,
내부 함수가 외부 함수의 변수에 접근할 수 있고, 외부 함수의 실행 컨텍스트가 종료된 이후에도 이러한 접근이 가능한 상태를 유지하는 것이 핵심이라고 볼 수 있다
유용하게 사용되는 경우
1. 데이터 은닉과 캡슐화: 클로저를 사용하여 특정 함수에 대한 접근을 제한. 객체 지향 프로그래밍에서의 프라이빗 변수와 유사한 효과
- 참고: 객체 지향 프로그래밍에서 프라이빗 변수는 클래스의 외부에서는 접근할 수 없고, 오직 클래스 내부의 메소드를 통해서만 접근하거나 수정할 수 있는 변수로 데이터를 은닉하고 객체의 상태를 외부로부터 보호할 때 사용
function 만들기카운터() {
let 카운트 = 0; // 이 변수는 만들기카운터 함수의 외부에서 접근할 수 없음
return {
증가: function() {
카운트 = 카운트 + 1;
return 카운트;
},
감소: function() {
카운트 = 카운트 - 1;
return 카운트;
}
};
}
const 카운터 = 만들기카운터();
console.log(카운터.증가()); // 1
console.log(카운터.증가()); // 2
console.log(카운터.감소()); // 1
2. 콜백 함수에서 변수 사용: 비동기 처리나 이벤트 리스너에서 클로저를 사용하면 콜백함수가 실행될 때 필요한 변수를 사용할 수 있다
function 외부함수(메시지) {
setTimeout(function 내부함수() {
console.log(메시지); // 외부함수의 메시지 변수에 접근
}, 1000);
}
외부함수('안녕하세요!');
예제 코드에서 setTimeout의 콜백 함수(내부함수)는 외부함수의 메시지 변수에 접근할 수 있다
3. 커링과 함수 프로그래밍: 커링은 함수의 인자를 여러 단계에 걸쳐 나눠서 적용할 수 있게 해주는 기법으로 커링 프로그래밍에 클로저가 중요한 역할을 한다
function 더하기(a) {
return function(b) {
return a + b; // 여기서 a는 더하기 함수의 매개변수입니다.
};
}
const 더하기5 = 더하기(5);
console.log(더하기5(2)); // 7
더하기 함수는 또 다른 함수를 반환하며, 반환된 함수는 더하기 함수의 매개변수 a에 접근할 수 있다
더하기 함수에 5라는 매개변수를 주어 더하기5 함수를 만드는 과정을 통해
더하기5 함수는 a를 5로한 함수가 된다
즉 function(b) { return 5 + b }; 인 것이다
더하기5 함수에 2를 매개변수로 주면 7이 반환된다
이렇게 할 수 있는 것은 자바스크립트에서 함수를 일급 객체로 취급하고,
함수가 또 다른 함수를 반환할 수 있으며,
클로저를 통해 외부 변수의 상태를 기억할 수 있기 때문이다
cf) 함수를 일급 객체로 취급한다는 말은 자바스크립트에서 함수를 변수에 할당할 수 있고, 다른 함수의 인자로 전달하거나, 함수에서 다른 함수를 반환할 수 있다는 의미이다
'Frontend' 카테고리의 다른 글
Promise와 Callback 차이 (0) | 2024.03.04 |
---|---|
비동기 함수 (0) | 2024.03.02 |
호이스팅 (0) | 2024.03.01 |
async / await 사용법 (0) | 2024.03.01 |
프론트엔드 면접 질문 앞으로 정리해나갈 것들 리스트 (0) | 2024.03.01 |