클로저에 대한 질문입니다
조회수 541회
안녕하세요. Javascript 공부 중 모르는 것이 있어 질문 드립니다.
for(var i=0; i<36; i++) {
document.getElementById("seat"+i).onclick = function(i) {
return function(event) {
showSeatStatus(i);
}
}(i); // 이 부분!!
}
이 코드에서 다른 건 다 이해가 되는데 onclick 이벤트 처리 함수 끝에 (i)
가 붙는 이유를 모르겠습니다.
Closure란 것은 무엇인지 알지만 저 부분만 잘 모르겠더군요.
저 부분을 없애면 또 함수가 제대로 작동하지 않습니다. ㅜㅜㅜ
- 아래는 제가 참고한 stackoverflow 링크입니다. stackoverflow
1 답변
-
실제 클릭이 실행되는 시점은 for문이 다 돌아서
i
값이36
이 된 후 입니다.제대로 동작하지 않는다고 하신 상황을 예측해 보자면, 모든 엘리먼트의 클릭 후 동작이 36번 인덱스만을 바라보고 동작할 겁니다.
실제 36번 인덱스에 해당하는 데이터 혹은 엘리먼트는 없을 것이고 어딘가에서 참조 에러가 나겠죠.
첨부해 주신 위 코드가 잘 이해가 안 되는 이유는 함정이 포함된 코드이기 때문입니다.
실제로 이해를 돕기 위한 코드는 아래와 같이 되어야 합니다.
for(var i=0; i<36; i++) { document.getElementById("seat"+i).onclick = function(index) { // fixed return function(event) { showSeatStatus(index); // fixed } }(i); // 이건 꼭 넣어주셔야 합니다. }
이렇게 되면 클로저에 바인딩 된 변수가 뭐가 될까요?
i
가index
라는 이름으로 바인딩 되어서 이 후에 클릭 이벤트가 발생해도i
값을 유지할 수 있어서 문제가 되지 않습니다.참고로 자바스크립트의 scope, Function Expression, IIFE도 추가로 알아야 위 질문하신 코드의 형태에 대해서 헤깔리지 않을 겁니다.
기억하세요. 비동기 코드 흐름 제어, 팩토리 패턴, 자바스크립트 안티 패턴 회피에 클로저는 유용합니다. 그 이유는 로컬 변수를 바인딩 할 수 있기 때문입니다.
위와 비슷한 현상을 해결 할 수 있는 다른 방법은
Array.forEach
를 사용하는 것인데, 질문의 상황은 배열을 순회하는 것이 아니므로 해당되지 않겠네요.ES6를 사용한 더 단순한 방법은
for(let i=0; i<36; i++) { // var -> let document.getElementById("seat"+i).onclick = function(event) { showSeatStatus(i); // use "i" }; }
댓글 입력