728x90
클로저(closure)의 개념
“클로저는 ‘함수’와 그 함수가 ‘선언됐을 때의 렉시컬 환경’의 조합이다”
더보기
☝ 잠깐(wait)!! 렉시컬 환경이란?
→ 식별자와 식별자에 바인딩된 값, 상위 스코프에 대한 참조를 가리키는 자료구조
함수를 일급 객체로 취급하는 함수형 프로그래밍에서 없어서는 안될 중요한 특성
< 예시1 >
function outerFunc() {
const x = 10;
const innerFunc = function () { console.log(x); };
innerFunc();
}
outerFunc(); // 10
실행 컨텍스트 관점
- 호출 시 각각의 스코프 체인을 순차적으로 검색하여 상위 스코프에 접근하여 함수를 실행
- innerFunc 함수 내부에서 변수 x 검색 → 검색 실패!
- outerFunc 내부에서 변수 x 검색 → 검색 성공!
< 예시 2 >
function outerFunc() {
const x = 10;
const innerFunc = function () { console.log(x); };
return innerFunc;
}
// 함수 outerFunc를 호출하면 내부 함수 innerFunc가 반환된다.
// 그리고 함수 outerFunc의 실행 컨텍스트는 소멸한다.
const inner = outerFunc();
inner(); // 10
실행 컨텍스트관점
- inner에 outerFunc()를 할당한 시점에서 outerFunc()의 실행 컨텍스트는 종료, 하지만 inner()를 실행할 시 그대로 동작함
- outerFunc() 호출 시, 실행컨텍스트 생성 및 innerFunc() 반환
- innerFunc는 외부 함수인 outerFunc의 x변수 참조 (클로저)
- 클로저 덕분에 innerFunc 반환 후 outerFunc의 실행 컨텍스트는 유지
- 따라서 다른 변수에 할당하여 컨텍스트가 종료되더라도 innerFunc의 클로저 덕에 변수 x에 접근 가능
클로저(closure)의 활용
정보의 은닉
의도치 않은 변경을 방지하도록 상태를 은닉하고, 특정 함수에게만 변경을 허용
< 예시 >
let num = 0;
const increase = function () {
return ++num;
}
console.log(increase()); // 1
console.log(increase()); // 2
console.log(increase()); // 3
더보기
☝ 위 코드는 num 변수 값이 increase()의 호출전까지 계속 유지되어야하고, 이를 increase()만이 변경가능해야 적절하게 동작
❗ 하지만(but)!! 전역적으로 선언했으므로 아무 함수에서나 변경될 우려가 있어 의도치 않은 상태 변경이 예상
< 클로저 사용 예시 >
const increase = (function () {
let num = 0;
return function () {
return ++num;
}
}());
console.log(increase()); // 1
console.log(increase()); // 2
console.log(increase()); // 3
더보기
✅ 클로저 사용을 통해 num을 함수 스코프 안으로 넣어 은닉하고, increase() 호출 시에만 변경 가능하게 하여 단점을 제거
상태 유지
현재 상태를 기억하고 변경된 최신 상태를 유지
< 예시 >
// html
<div class="box" style="width: 100px; height: 100px;
background: red;"></div>
// js
const box = document.querySelector('.box');
const toggleBtn = document.querySelector('.toggle');
const toggle = (function () {
const isShow = false;
return function () {
box.style.display = isShow ? 'block' : 'none';
isShow = !isShow;
};
})();
toggleBtn.addEventListener('click', toggle);
더보기
✅ 클로저를 사용한 위 코드는 toggle함수가 isShow의 상태를 기억하면서(클로저) 박스의 스타일값을 클릭 이벤트을 통해 변경