JS 코드의 동작을 살펴보면 코드를 실행하면 스크립트내의 선언된 변수들이 Lexical 환경에 올라간다.
이후 순차적으로 실행되는데, let one; 을 만났을 때 one : undefined 되며 사용가능 상태로 바뀐다.
one = 1 을 수행하고 , 마지막 라인인 addOne(5); 로 가서 함수가 실행되면 새로운 Lexical 환경이 생성된다.
예시 2)
정리)
--> 이와 같은 것을 closure
라고 한다
Closure 는 함수와 렉시컬 환경의 조합이다
함수가 생성될 당시의 외부 변수를 기억하고, 생성된 이후에도 그 변수에 계속해서 접근할 수 있는 기능이다.외부함수의 실행이 끝난 경우에도 내부 함수가 외부 함수의 변수에 접근할 수있다.
--> add10 과 add3은 서로 다른 환경을 가지고 있다.
클로저가 가장 유용하게 사용되는 상황은 현재 상태를 기억하고 변경된 최신 상태를 유지하는 것이다.
var toggle = (function () {
var isShow = false;
// ① 클로저를 반환
return function () {
box.style.display = isShow ? 'block' : 'none';
// ③ 상태 변경
isShow = !isShow;
};
})();
// ② 이벤트 프로퍼티에 클로저를 할당
toggleBtn.onclick = toggle;
var counter = 0;
function increase() {
return ++counter;
}
incleaseBtn.onclick = function () {
count.innerHTML = increase();
};
위 코드는 잘 동작하지만 오류를 발생시킬 가능성을 내포하고 있는 좋지 않은 코드다. 변수 counter는 전역 변수이기 때문에 언제든지 누구나 접근할 수 있고 변경할 수 있다. 이는 의도치 않게 값이 변경될 수 있다는 것을 의미한다. 만약 누군가에 의해 의도치 않게 전역 변수 counter의 값이 변경됐다면 이는 오류로 이어진다.
이를 지역변수로 구현한다면 ??
function increase() {
// 카운트 상태를 유지하기 위한 지역 변수
var counter = 0;
return ++counter;
}
incleaseBtn.onclick = function () {
count.innerHTML = increase();
};
-> 지역 변수로 사용하면 오류의 확률이 줄지만 , 함수가 호출될 때마다 counter 값이 0으로 초기화되기 때문에 언제나 1이 표시된다..
클로저를 사용하여 해결해보자 !
var increase = (function () {
// 카운트 상태를 유지하기 위한 자유 변수
var counter = 0;
// 클로저를 반환
return function () {
return ++counter;
};
}());
incleaseBtn.onclick = function () {
count.innerHTML = increase();
};