개발자

클로저 문제에 대해 질문이 있습니다.

2022년 12월 16일조회 243

아주 유명한 클로저 문제인데요 해당 코드에서 setTimeout의 콜백함수가 10번 생기게 되는데, 이 때 바깥의 func함수의 변수 i는 10개가 생기는 건가요? 아니면 한 개만 생기는건가요?

이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.
profile picture
익명님의 질문

답변 2

손정현님의 프로필 사진

안녕하세요! 우선 답변부터 드리자면 1개만 생기게 되는 것으로 알고있습니다. i를 var로 선언하셨기 때문에 func 함수의 스코프로 할당이 되는데요. 이 때문에 setTimeout에 제공하는 arrow function 속 i도 func 스코프의 i를 뜻하게 됩니다. 만약 i를 let으로 선언하셨다면, ex) for ( let i = 0; i < 10; i++ ) { setTimeout(() => { console.log(i) }) } 반복문이 한번 돌때마다 i는 block 스코프로 할당이되고 setTimeout에 제공하는 arrow function도 해당 block 스코프 속 i를 사용하게 됩니다. 그래서 var를 사용한 예시는 setTimeout의 콜백이 돌때는 이미 for 반복문이 다 돌고 난 뒤고 func의 스코프를 사용하기 때문에 console.log가 다 10을 찍는 반면, let을 사용한 예시는 for 반복문이 다 돌았어도 setTimeout의 콜백이 for 반복문의 개별 스코프를 사용하기 때문에 console.log가 0~9까지 올바르게 찍는 것을 알 수 있습니다. 이 개념은 JS의 호이스팅과 스코프 개념을 알고 계시면 이해가 더 빠르실 것 같습니다. 참고하시면 좋을법한 링크들 첨부합니다 :) - https://ui.toast.com/weekly-pick/ko_20160311 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures#lexical_scoping - https://developer.mozilla.org/en-US/docs/Glossary/Hoisting - https://www.freecodecamp.org/news/lexical-scope-in-javascript/

황민호님의 프로필 사진

func 함수의 변수 i는 하나만 됩니다. setTimeout의 콜백 함수가 10번 발생하면 매번 i의 값을 출력하게 되어 10이 됩니다. 이는 setTimeout 콜백 함수 내에서 i의 값이 클로저에 캡처되지 않기 때문에 항상 참조하게 됩니다.

황민호님의 프로필 사진

황민호

Kakao General Developer2022년 12월 18일

JavaScript에서 함수가 자체 범위 외부에서 정의된 변수에 액세스할 때 클로저가 생성됩니다. 이는 외부 함수 실행이 완료된 후에도 함수가 외부 변수를 참조하고 액세스할 수 있음을 의미합니다. 위의 예에서 setTimeout 콜백 함수는 외부 func 함수에 정의된 변수 i에 액세스하고 있습니다. 그러나 setTimeout 콜백 함수는 for 루프 실행이 완료될 때까지 실행되지 않기 때문에 콜백 함수가 최종적으로 실행될 때 i 값은 10이 됩니다. 루프 변수는 콜백 함수 내의 클로저에 캡처되지 않고 콜백 함수가 실행되기 전에 값을 변경할 수 있기 때문에 setTimeout과 같은 비동기 함수에서 루프 변수를 사용할 때 흔히 발생하는 문제입니다. 이 문제에 대한 한 가지 해결책은 루프 내에서 즉시 호출 함수 표현식(IIFE)을 사용하여 클로저를 생성하고 각 반복에서 루프 변수의 현재 값을 캡처하는 것입니다. 예를 들어 i 를 let으로 선언하는 것으로 해결할 수 있습니다.

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

목록으로

실무, 커리어 고민이 있다면

새로운 질문 올리기

지금 가입하면 모든 질문의 답변을 볼 수 있어요!