2.5 클로저

클로저

  • 클로저란 한문장으로 말하면 "함수와 함수외부 변수간의 관계"를 뜻한다
  • 클로저 => 스코프, 비동기, var(쓰레기)
  • 클로저가 문제다x
  • 클로저를 사용해서 해결하는 문제
  • for문(반복문)과 비동기를 함께 사용하면 종종 발생
function a() {
	for (var i = 0; i < 5; i++) {
    	setTimeout(() => {
        	console.log(i)
        }, i * 1000);
    }
}
a();

* 결과: 5, 5, 5, 5, 5
* 해결법은 var을 let으로 바꾸거나 즉시 함수를 사용한다

에러가 일어나는 이유

  • var로 i를 선언하게 되면 i는 a함수의 스코프에 위치하게 된다.
  • for문으로 인해 setTimeout함수는 각각 스코프를 5개를 만든다.
  • setTimeout은 비동기 함수라서 호출스택이 비었을때 실행이된다
  • setTimeout에서 i를 가르키는건 i=5인 상태를 가리킨다.
  • 그래서 결과가 5, 5, 5, 5, 5가 나온다

해결방법

  1. 즉시 실행함수
function a() {
	for (var i = 0; i < 5; i++) {
    	(function(j) {
        	setTimeout(() => {
        		console.log(i)
        	}, i * 1000);
        })(i)
    }
}
a();

  • for문 안에 함수를 하나 더 만들어서 바로 실행을 한다
  • 그러면 각 함수에 i를 매개변수로 전달하게 된다
  • 각각 함수에 i = 0...4까지 각각 전달된 상태로 setTimeout은 백그라운에 저장된다
  1. var대신 let사용하기
function a() {
	for (let i = 0; i < 5; i++) {
    	setTimeout(() => {
        	console.log(i)
        }, i * 1000);
    }
}
a();
  • i를 let으로 선언하게되면 var와 달리 i는 a스코프가 아니라 for 스코프에 지정이 된다.
  • for안에 있는 setTimeout은 i를 0...4까지 각각 가지고 백그라운드에 저장이 된다

PS: 오타: 그림에 setTime(5) => setTime(4)로 바꾸어야함

좋은 웹페이지 즐겨찾기